C#反射从泛型基类中的字段获取值

C#反射从泛型基类中的字段获取值,c#,generics,reflection,fieldinfo,C#,Generics,Reflection,Fieldinfo,问题是,我们无法获取仅驻留在具有泛型类型的基类中的字段(非泛型)的值。 请参阅下面的代码片段。召唤 f.GetValue(a) 将引发异常,并显示以下消息:无法对类型为Type.ContainsGenericParameters为true的字段执行后期绑定操作 class Program { static void Main(string[] args) { Type abstractGenericType = typeof (ClassB<>);

问题是,我们无法获取仅驻留在具有泛型类型的基类中的字段(非泛型)的值。 请参阅下面的代码片段。召唤

f.GetValue(a)
将引发异常,并显示以下消息:无法对类型为Type.ContainsGenericParameters为true的字段执行后期绑定操作

class Program
{
    static void Main(string[] args)
    {
        Type abstractGenericType = typeof (ClassB<>);
        FieldInfo[] fieldInfos =
            abstractGenericType.GetFields(BindingFlags.Public |  BindingFlags.Instance);

        ClassA a = new ClassA("hello");
        foreach(FieldInfo f in fieldInfos)
        {
            f.GetValue(a);// throws InvalidOperationhException 
        }
    }
}

internal class ClassB<T>
{
    public string str;
    public ClassB(string s)
    {
        str = s;
    }
}

internal class ClassA : ClassB<String>
{
    public ClassA(string value) : base(value)
    {}
}

谢谢你

我想问题出在这一点上,泛型类是用特定类型动态编译的。泛型类型也可以定义为

internal class ClassB<T>
{
    public T value;

    public string str;
    public ClassB(string s)
    {
        str = s;
    }
}
内部类B
{
公共价值观;
公共字符串str;
公共类B(字符串s)
{
str=s;
}
}

然后,获取字段“value”的值时会遇到问题。解决方法是使用.GetType()直接检索类型,或者创建一个新的基类,而不使用包含要访问的字段的泛型参数。

如果您灵活且愿意使用属性而不是字段,通过在泛型基类上放置一个非泛型接口,您可以完成类似于所需的任务。这里是原始代码的重新分解版本,显示了更改和概念

    class Program
    {
        public static void Main(string[] args)
        {
            Type interfaceType = typeof(IGetStr);
            PropertyInfo[] propertyInfos = interfaceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            ClassA a = new ClassA("hello");

            foreach (PropertyInfo p in propertyInfos)
            {
                var myValue = p.GetValue(a, null); // does not throw InvalidOperationException 
            }
        }
    }

    internal interface IGetStr
    {
        string StringValue { get; set; }
    }

    internal class ClassB<T> : IGetStr
    {
        public string str;

        public ClassB(string s)
        {
            str = s;
        }

        public string StringValue
        {
            get
            {
                return str;
            }
            set
            {
                str = value;
            }
        }
    }

    internal class ClassA : ClassB<String>
    {
        public ClassA(string value)
            : base(value)
        { }
    }

张贴的问题没有多大意义。您必须使用对象实例来调用GetValue()。因此,只需使用
a.GetType()
即可获得具体的泛型类型,无需遍历不完整的类型。
    class Program
    {
        public static void Main(string[] args)
        {
            Type interfaceType = typeof(IGetStr);
            PropertyInfo[] propertyInfos = interfaceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            ClassA a = new ClassA("hello");

            foreach (PropertyInfo p in propertyInfos)
            {
                var myValue = p.GetValue(a, null); // does not throw InvalidOperationException 
            }
        }
    }

    internal interface IGetStr
    {
        string StringValue { get; set; }
    }

    internal class ClassB<T> : IGetStr
    {
        public string str;

        public ClassB(string s)
        {
            str = s;
        }

        public string StringValue
        {
            get
            {
                return str;
            }
            set
            {
                str = value;
            }
        }
    }

    internal class ClassA : ClassB<String>
    {
        public ClassA(string value)
            : base(value)
        { }
    }
var result = ((IGetStr)a).StringValue;