'System.Collections.Generic.IList<object>' does not contain a definition for 'Add' when using 'dynamic' and 'ExpandoObject'

后端 未结 2 1150
攒了一身酷
攒了一身酷 2021-02-18 15:30

Say that I have a class, Foo, looking something like this:

public class Foo : IFoo
{
    public Foo()
    {
        Bars = new List();
    }
    p         


        
2条回答
  •  天命终不由人
    2021-02-18 16:15

    This is a known dynamic binding issue.

    Here are some work arounds.

    Use ICollection instead:

    void Main()
    {
        IFoo foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add(a);
        foo.Bars.Add(b); 
    }
    
    public interface IFoo
    {
        ICollection Bars { get; set; }
    }
    
    public class Foo : IFoo
    {
        public Foo()
        {
            Bars = new List();
        }
    
        public ICollection Bars { get; set; }
    }
    

    Or straight up List:

    public interface IFoo
    {
        List Bars { get; set; }
    }
    
    public class Foo : IFoo
    {
        public Foo()
        {
            Bars = new List();
        }
    
        public List Bars { get; set; }
    }
    

    Or use dynamic foo:

    void Main()
    {
        dynamic foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add(a);
        foo.Bars.Add(b); 
    }
    

    Or don't dynamic bind add, by casting to object:

    void Main()
    {
        IFoo foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add((object)a); 
        foo.Bars.Add((object)b); 
    }
    

    Or be more expressive using a third party framework like my impromptu interface with ActLike & Prototype Builder Syntax (in nuget).

    using ImprmoptuInterface;
    using Dynamitey;
    void Main()
    {
        dynamic New = Builder.New();
    
        IFoo foo = Impromptu.ActLike(
                       New.Foo(
                           Bars: New.List(
                                     New.Obj(Prop:10000),
                                     New.Obj(Prop:"Some Text")
                                 )
                           )
                       );
    }
    
    public interface IFoo
    {
        IList Bars { get; set; }
    }
    

提交回复
热议问题