匿名类型和动态列表......困惑
我发现 .NET 内部的某些东西的工作方式与我的预期略有不同。我粘贴的代码没有意义,但它是我拥有的更复杂函数的压缩版本。我本质上是获取匿名类型信息作为参数(尚未创建匿名类型的实例),并且我需要创建该类型的列表,填充它,然后返回该列表。现在,我找到了解决方案,但我想知道为什么方法 B 有效但方法 A 无效。
方法 A:
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" }));
}
方法 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" }));
}
再说一次,我不是在寻找解决方案,只是好奇为什么方法 B 有效但方法 A 无效。
谢谢!
I found something inside .NET that works a bit differently that I would have expected. The code I am pasting won't make sense, but it is a condensed version of a much more complicated function I have. I'm essentially getting the anonymous type information as a parameter (no instance created yet of the anonymous type) and I need to create a list of that type, populate it, and then return the list. Now, I found a solution, but I wanted to know why Method B works but not Method A.
Method A:
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" }));
}
Method 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" }));
}
Again, I'm not looking for a solution, just curious why Method B works but not Method A.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为在方法 B 中,您使用的是显式的 IList.Add(object) ,它接受一个对象并尝试将其转换为匿名类型。在方法 A 中,您有一个
List
并且您正在使用通用 Add 方法并尝试添加一个对象,但您收到RuntimeBinderException
因为它期望正确铸造的类型。如果您没有使用dynamic
,您会看到编译器错误。要使用显式IList.Add
,请将方法 A 更改为Because in your method B, you are using the explicit
IList.Add(object)
which takes an object and tries to cast it to your anonymous type. In method A you have aList<anonymous type>
and you're using the generic Add method and trying to Add an object, but you get theRuntimeBinderException
because it is expecting the correctly casted type. If you weren't using adynamic
you'd see the compiler error. To use the explicitIList.Add
, change your method A with要使方法 A 起作用,您所需要做的就是
动态
转换您要添加的激活器结果。很多人没有意识到,C# 动态调用实际上默认使用静态类型来确定方法签名。因此,通过将参数转换为动态,您可以告诉它使用运行时类型。All you need to do to make Method A work, is
dynamic
cast the Activator result that you are adding. Many people don't realize that C# dynamic invocation actually uses static types by default to determine the method signature. So by casting the argument to dynamic as well you are telling it to use the runtime type.