将泛型添加到动态集合时的C#奇怪行为

tle*_*eef 4 c# generics dynamic

作品

private void Add<H>(H toAdd, IList<dynamic> list)
{
     list.Add(toAdd);
}
Run Code Online (Sandbox Code Playgroud)

不行

private void Add<H>(IList<H> toAdd, IList<IList<dynamic>> list)
{
     list.Add(toAdd);
}
Run Code Online (Sandbox Code Playgroud)

你可以想象,错误是

The best overloaded method match for 'System.Collections.Generic.ICollection<System.Collections.Generic.IList<dynamic>>.Add(System.Collections.Generic.IList<dynamic>)' has some invalid arguments
Run Code Online (Sandbox Code Playgroud)

如果有人知道为什么会这样,甚至更好,如何解决它,我很好奇.我认为它与Generic Variance有关,但动态使我不太确定.

谢谢,汤姆

编辑

   //doesn't work
   private void Add<H>(IList<H> toAdd, IList<IList<dynamic>> list) where H : object
   {
      list.Add(toAdd);
   }

   //works
   //this isn't good enough however because I only want to be able to
   //have one type of object in toAdd
   private void Add(IList<object> toAdd, IList<IList<dynamic>> list)
   {
      list.Add(toAdd);
   }

   //works
   private void Add<H>(IList<H> toAdd, IList<IList<dynamic>> list)
   {
      list.Add(toAdd.Cast<dynamic>().ToList());
   }

   private void Foo()
   {
      //works
      IList<dynamic> list1 = new List<object>();
      //works
      IList<object> list2 = new List<dynamic>();
      //works
      IList<IList<dynamic>> list4 = new List<IList<object>>();
      //works
      IList<IList<object>> list3 = new List<IList<dynamic>>();
   }
Run Code Online (Sandbox Code Playgroud)

我添加了几个例子(并不是所有令人惊讶的)只是为了说明

Tod*_* Li 6

那是因为你不能投IList<H>一个IList<dynamic>.想象一下会发生什么:

IList<H> myList = new List<H>(...);
IList<dynamic> myDynamicList = myList; // assuming this would compile
myDynamicList.Add(new Foo()); // boom
Run Code Online (Sandbox Code Playgroud)

您可以尝试保留列表IEnumerable<dynamic>而不是IList<dynamic>,因为IEnumerable<out T>有一个协变类型参数.