在c#中查找动态对象的类型

Finding the type of dynamic objects in c#

我有一个动态对象列表。在运行时,我想在列表中找到对象的类型,以便我可以实例化该类型的新列表。

List<dynamic> list1= new List<dynamic>() { new Test() {ID = 1} }

我想知道 ID 是 int 类型,以便我可以在 Activator.CreateInstance 语句中使用它。当我尝试使用以下语句获取类型时,我总是得到 "object"

Type typeInArgument = list1.GetType().GenericTypeArguments[0];

有没有办法得到这种类型?我看到一些类似的问题,建议使用

Type unknown = ((ObjectHandle)list1).Unwrap().GetType();

但这不会为列表编译。

我需要建议来解决这个问题。

A List<dynamic> 没有 特定的内部类型。 dynamic 的全部意义在于它可以是任何东西。

相反,您可以获取列表中项目的类型:list1[0].GetType()
请注意,不能保证下一个项目是同一类型。

听起来它工作得很好。

因为您使用的是 dynamic,所以列表元素 的最大公分母是 object。仅仅因为你碰巧只有一个元素在那里,并不意味着 运行时间可以保证这一点。

因此,您可能需要对您要查找的内容进行特殊处理。

Type ret;
if (list1.Count == 0)
    ret = typeof(object);
else
    ret = list1[0].GetType();

当然,如果您提供给我们的代码是按字面意思理解的,则该检查是多余的。但我希望你明白这一点。

您还可以在列表中添加对 运行 的检查,如果需要的话,检查是否所有项目都是同一类型。

总的来说,这听起来可能不是使用 dynamic 的好时机。如果您需要匿名类型,我建议您为此转向具体类型。如果您正在执行此处的操作,只需将其键入 List<Test>.

当然,如果您要查找的只是此列表的一个副本,那么您可以这样做并确保它是正确的。为了可读性,我这样做是为了 foreach,但 LINQ 在这里是一个不错的选择。

List<object> ret = new List<object>();
foreach (var v in list1)
{
    var type = v.GetType();

    ret.Add(/* new instance of type */);
}
return ret;

当然,请记住,这并不能保证您对包含的类型有更多了解,当您尝试实际阅读结果列表时,您会再次遇到同样的问题。

我真的建议在这里重新评估您对动态的使用。它确实允许一些原本不可能实现的事情,因此您可能会选择坚持使用它,但值得再三考虑。