Dynamic 匿名类型和动态的列表。。。困惑的
我在.NET中发现了一些与我预期的有点不同的东西。我粘贴的代码没有意义,但它是我拥有的一个更复杂函数的浓缩版本。我基本上是将匿名类型信息作为一个参数来获取(还没有创建匿名类型的实例),我需要创建该类型的列表,填充它,然后返回该列表。现在,我找到了一个解决方案,但我想知道为什么方法B有效而方法a无效 方法A:Dynamic 匿名类型和动态的列表。。。困惑的,dynamic,c#-4.0,anonymous-types,Dynamic,C# 4.0,Anonymous Types,我在.NET中发现了一些与我预期的有点不同的东西。我粘贴的代码没有意义,但它是我拥有的一个更复杂函数的浓缩版本。我基本上是将匿名类型信息作为一个参数来获取(还没有创建匿名类型的实例),我需要创建该类型的列表,填充它,然后返回该列表。现在,我找到了一个解决方案,但我想知道为什么方法B有效而方法a无效 方法A: static void Main(string[] args) { var newItem = new { ID = Guid.NewGuid(), Name = "Test" }
static void Main(string[] args)
{
var newItem = new { ID = Guid.NewGuid(), Name = "Test" };
dynamic list;
list = Activator.CreateInstance(typeof(List<>).MakeGenericType(newItem.GetType()));
list.Add(newItem);
list.Add(Activator.CreateInstance(newItem.GetType(), new object[] { Guid.NewGuid(), "Test 2" }));
}
static void Main(字符串[]args)
{
var newItem=new{ID=Guid.NewGuid(),Name=“Test”};
动态列表;
list=Activator.CreateInstance(typeof(list).MakeGenericType(newItem.GetType());
列表。添加(新项);
Add(Activator.CreateInstance(newItem.GetType(),新对象[]{Guid.NewGuid(),“Test 2”});
}
方法B:
static void Main(string[] args)
{
var newItem = new { ID = Guid.NewGuid(), Name = "Test" };
System.Collections.IList list;
list = (System.Collections.IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(newItem.GetType()));
list.Add(newItem);
list.Add(Activator.CreateInstance(newItem.GetType(), new object[] { Guid.NewGuid(), "Test 2" }));
}
static void Main(字符串[]args)
{
var newItem=new{ID=Guid.NewGuid(),Name=“Test”};
System.Collections.IList列表;
list=(System.Collections.IList)Activator.CreateInstance(typeof(list).MakeGenericType(newItem.GetType());
列表。添加(新项);
Add(Activator.CreateInstance(newItem.GetType(),新对象[]{Guid.NewGuid(),“Test 2”});
}
同样,我不是在寻找解决方案,只是好奇为什么方法B有效,而方法a无效
谢谢 因为在方法B中,您使用的是显式的
IList.Add(object)
,它接受一个对象并尝试将其强制转换为匿名类型。在方法A中,您有一个列表
,您正在使用泛型Add方法并尝试添加一个对象,但是您得到了RuntimeBinderException
,因为它需要正确的强制类型。如果您没有使用动态,您将看到编译器错误。要使用显式的IList.Add
,请使用
((IList)list).Add(
Activator.CreateInstance(newItem.GetType(),
new object[] { Guid.NewGuid(), "Test 2" }));
要使方法A起作用,只需dynamic
cast您正在添加的激活器结果。许多人没有意识到C#动态调用实际上默认使用静态类型来确定方法签名。因此,通过将参数强制转换为dynamic,您告诉它使用运行时类型
static void Main(string[] args)
{
var newItem = new { ID = Guid.NewGuid(), Name = "Test" };
dynamic list;
list = Activator.CreateInstance(typeof(List<>).MakeGenericType(newItem.GetType()));
list.Add(newItem);
list.Add((dynamic)Activator.CreateInstance(newItem.GetType(), new object[] { Guid.NewGuid(), "Test 2" }));
}
static void Main(字符串[]args)
{
var newItem=new{ID=Guid.NewGuid(),Name=“Test”};
动态列表;
list=Activator.CreateInstance(typeof(list).MakeGenericType(newItem.GetType());
列表。添加(新项);
Add((动态)Activator.CreateInstance(newItem.GetType(),新对象[]{Guid.NewGuid(),“Test 2”});
}
为什么要在该场景中使用dynamic?您正在创建一个通用列表。您也没有说您收到的错误或警报可能与此相关。啊!现在一切都有意义了。谢谢你的帮助!同样,我使用方法B是因为它是一个更干净的解决方案,这有助于澄清为什么方法a首先不起作用,“测试2”});效果很好。再次感谢!