Say that I have a class, Foo, looking something like this:
public class Foo : IFoo
{
public Foo()
{
Bars = new List<dynamic>();
}
public IList<dynamic> Bars { get; set; }
}
The interface IFoo looks like:
public interface IFoo
{
IList<dynamic> Bars { get; set; }
}
Now, when I do the following:
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); // Throws an 'System.Collections.Generic.IList<object>' does not contain a definition for 'Add' - exception!!!!!
foo.Bars.Add(b); // Same here!!!!!
What am I doing wrong here?????
This is a known dynamic binding issue.
Here are some work arounds.
Use ICollection<dynamic>
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<dynamic> Bars { get; set; }
}
public class Foo : IFoo
{
public Foo()
{
Bars = new List<dynamic>();
}
public ICollection<dynamic> Bars { get; set; }
}
Or straight up List<dynamic>
:
public interface IFoo
{
List<dynamic> Bars { get; set; }
}
public class Foo : IFoo
{
public Foo()
{
Bars = new List<dynamic>();
}
public List<dynamic> 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<ExpandoObject>();
IFoo foo = Impromptu.ActLike(
New.Foo(
Bars: New.List(
New.Obj(Prop:10000),
New.Obj(Prop:"Some Text")
)
)
);
}
public interface IFoo
{
IList<dynamic> Bars { get; set; }
}
I'm not sure if this subverts your particular use case, but:
Try explicitly casting Bars
to System.Collections.IList
.
((System.Collections.IList)foo.Bars).Add(a);
Source: https://stackoverflow.com/a/9468123/364
Alternatively, just redefine Bars
as IList
rather than IList<dynamic>
in your interface + class.