获取泛型类的属性

时间:2013-01-02 21:25:36

标签: c#

我有一个泛型类,一个对象值obj.GetType().GetGenericTypeDefinition() == typeof(Foo<>)

class Foo<T>
{
    public List<T> Items { get; set; }
}

如何从Items获取obj的值?请注意,objObject,我无法将obj投反为Foo,因为我不知道T是什么。

我希望对此使用反射,但每次执行GetProperty("Items")时都会返回null。但是,如果有人知道一个好的方法,无论如何都要做到这一点。

假设我的代码如下:

//just to demonstrate where this comes from
Foo<int> fooObject = new Foo<int>();
fooObject.Items = someList;
object obj = (object)fooObject;

//now trying to get the Item value back from obj
//assume I have no idea what <T> is
PropertyInfo propInfo = obj.GetType().GetProperty("Items"); //this returns null
object itemValue = propInfo.GetValue(obj, null); //and this breaks because it's null

5 个答案:

答案 0 :(得分:53)

你应该可以使用:

Type t = obj.GetType();

PropertyInfo prop = t.GetProperty("Items");

object list = prop.GetValue(obj);

当然,您无法直接转换为List<T>,因为您不知道类型T,但您仍然可以获得{{1}的值}}


编辑:

以下是一个完整的示例,以演示此工作:

Items

答案 1 :(得分:10)

@ReedCopsey是绝对正确的,但如果你真的问的问题是“如何删除类型的一般细节?”,这里有一些“反思的乐趣”:

public void WhatsaFoo(object obj)
{
    var genericType = obj.GetType().GetGenericTypeDefinition();
    if(genericType == typeof(Foo<>))
    {
        // Figure out what generic args were used to make this thing
        var genArgs = obj.GetType().GetGenericArguments();

        // fetch the actual typed variant of Foo
        var typedVariant = genericType.MakeGenericType(genArgs);

        // alternatively, we can say what the type of T is...
        var typeofT = obj.GetType().GetGenericArguments().First();

        // or fetch the list...
        var itemsOf = typedVariant.GetProperty("Items").GetValue(obj, null);
    }
}

答案 2 :(得分:3)

这样的事情可以解决问题:

var foo = new Foo<int>();
foo.Items = new List<int>(new int[]{1,2,3});

// this check is probably not needed, but safety first :)
if (foo.GetType().GetProperties().Any(p => p.Name == "Items"))
{
    var items = foo.GetType().GetProperty("Items").GetValue(foo, null);
}

答案 3 :(得分:0)

您必须使用 System.Reflection 命名空间才能成功执行该程序。

此程序为您提供 任何通用类的属性名称和值

您可以在C# Online Rexter Tool Compiler

上查看此代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

答案 4 :(得分:0)

大家好,我一直在为通用类型遇到同样的问题,最后找到了获得价值的解决方案 --------达到目的的方法的小代码段------------------

    public void printFields()
    {
        // Is the list empty
        if (this.list_.Count == 0)
        {
            //Y => Forced exit no object info
            return;
        }

        try
        {
            // Get first item from list
            T item = this.list_[0];

            // Get the type of object
            //**Type thisType = item.GetType();

            // Get array of all fields
            FieldInfo[] thisFieldInfo = item.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            // Loop through all fields and show its info
            for (int ix = 0; ix < thisFieldInfo.Length; ix++)
            {
                // Get Field value
                String strVal = thisFieldInfo[ix].GetValue(item).ToString();

                // Display item
                Console.WriteLine("'{0}' is a {1} and has value {2}", thisFieldInfo[ix].Name, thisFieldInfo[ix].FieldType, strVal);
            }


        }
        catch (SecurityException e)
        {
            Console.WriteLine("Exception: " + e.Message);
        }
    }