'Système.Collection.Générique.IList "ne contient pas de définition pour "ajouter" lors de l'utilisation de "dynamic" et "ExpandoObject"

Dire que j'ai une classe, Toto, à la recherche de quelque chose comme ceci:

public class Foo : IFoo
{
    public Foo()
    {
        Bars = new List<dynamic>();
    }
    public IList<dynamic> Bars { get; set; }
}

l'interface IFoo ressemble à:

public interface IFoo
{
    IList<dynamic> Bars { get; set; }
}

Maintenant, quand je fais le code suivant:

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!!!!!

Ce que je fais mal?????

18
demandé sur wonea 2013-04-10 12:35:55

2 réponses

Ceci est une liaison dynamique connue problème.

Voici quelques solutions.

Utiliser ICollection<dynamic> au lieu de:

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; }
}

Ou droites 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; }
}

Ou utiliser 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); 
}

Ou ne pas dynamique bind add, par coulée 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); 
}

OU être plus expressif en utilisant un tiers comme mon interface impromptu avec ActLike& Prototype Builder Syntaxe (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; }
}
22
répondu jbtule 2018-04-24 14:31:14

Je ne suis pas sûr que cela subverse votre cas particulier d'utilisation, mais:

Essayez explicitement casting BarsSystem.Collections.IList.

((System.Collections.IList)foo.Bars).Add(a);

Source:https://stackoverflow.com/a/9468123/364

alternativement, il suffit de redéfinir BarsIList plutôt que IList<dynamic> dans votre classe d'interface +.

2
répondu Matt Mitchell 2017-05-23 10:31:07