c# - 对继承泛型类型的反射(reflection)

标签 c# generics reflection

我在 C# 中遇到反射问题,我找不到答案。

我有一个继承自泛型的类,我试图从这个类中检索 T 的类型,但事实证明我做不到!

这是一个例子:

class Products : List<Product>
{}

问题是在运行时我不知道 T 的类型。所以我尝试这样获取类型:

Type itemsType = destObject.GetType().GetGenericArguments()[0]

没有成功。

这是我的方法:

public static object Deserialize(Type destType, XmlNode xmlNode)
    {         
        object destObject = Activator.CreateInstance(destType);

        foreach (PropertyInfo property in destType.GetProperties())
            foreach (object att in property.GetCustomAttributes(false))
                if (att is XmlAttributeAttribute)
                    property.SetValue(destObject, xmlNode.Attributes[property.Name].Value, null);
                else if (att is XmlNodeAttribute)
                {
                    object retObject = Deserialize(property.PropertyType, xmlNode.Nodes[property.Name]);
                    property.SetValue(destObject, retObject, null);
                }

        if (destObject is IList)
        {
            Type itemsType = destObject.GetType().GetGenericArguments()[0];
            foreach (XmlNode xmlChildNode in xmlNode.Nodes)
            {
                object retObject = Deserialize(itemsType, xmlNode);
                ((IList)destObject).Add(retObject);
            }
        }

        return destObject;
    }        

想法是读取一个xml文件并将其转换为一个对象:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SETTINGS>
  <PRODUCTS>
    <PRODUCT NAME="ANY" VERSION="ANY" ISCURRENT="TRUE" />
    <PRODUCT NAME="TEST1" VERSION="ANY" ISCURRENT="FALSE" />
    <PRODUCT NAME="TEST2" VERSION="ANY" ISCURRENT="FALSE" />
  </PRODUCTS>
  <DISTRIBUTIONS>
    <DISTRIBUTION NAME="5.32.22" />
  </DISTRIBUTIONS>
</SETTINGS>

在这种情况下,节点 PRODUCTS 将是我继承自 List 的集合

关于如何做到这一点有什么想法吗?

谢谢大家

最佳答案

Products类不是通用的,所以 GetGenericArguments不返回任何东西。

你需要获取基类型的泛型参数,像这样:

Type itemType = destObject.GetType().BaseType.GetGenericArguments()[0];

但是,这不是弹性的;如果引入中间的非泛型基类型,它将失败。
相反,您应该找到 IList<T> 的类型参数实现。

例如:

Type listImplementation = destObject.GetType().GetInterface(typeof(IList<>).Name);
if (listImplementation != null) {
    Type itemType = listImplementation.GetGenericArguments()[0];
    ...
}

关于c# - 对继承泛型类型的反射(reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4425657/

相关文章:

c# - EntityFramework7 - 约定、属性和配置

c# - 在 WPF 的 DoubleAnimation 期间更新 ViewModel 中的属性

c# - 如何在 C# 中存储不同通用事物的列表

java - Play Framework 2.5.12 - 从调用中获取方法

c# - 遍历对象集合 c#

c# - 需要帮助在 C# Web 表单应用程序中创建日期选择器

c# - 单独项目中的 EF5 模型看不到 DbContext 方法

Java 泛型捕获列表<?>

c# - generic 和 double 操作

c# - 如何在不使用反射的情况下检查 .NET 程序集