获取generics类的属性

我有一个generics类,以及一个对象值,其中obj.GetType().GetGenericTypeDefinition() == typeof(Foo)

 class Foo { public List Items { get; set; } } 

如何从obj获取Items的值? 记住, obj是一个Object ,我不能把obj当作Foo因为我不知道T是什么。

我希望为此使用reflection,但每次我执行GetProperty("Items")它都返回null。 但是,如果有人知道一个很好的方法,无需反思就可以做到这一点。

假设我的代码如下所示:

 //just to demonstrate where this comes from Foo fooObject = new Foo(); fooObject.Items = someList; object obj = (object)fooObject; //now trying to get the Item value back from obj //assume I have no idea what  is PropertyInfo propInfo = obj.GetType().GetProperty("Items"); //this returns null object itemValue = propInfo.GetValue(obj, null); //and this breaks because it's null 

你应该可以使用:

 Type t = obj.GetType(); PropertyInfo prop = t.GetProperty("Items"); object list = prop.GetValue(obj); 

当然,您无法直接转换为List ,因为您不知道类型T ,但您仍然可以获取Items的值。


编辑:

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

 // Define other methods and classes here class Foo { public List Items { get; set; } } class Program { void Main() { //just to demonstrate where this comes from Foo fooObject = new Foo(); fooObject.Items = new List { 1, 2, 3}; object obj = (object)fooObject; //now trying to get the Item value back from obj //assume I have no idea what  is PropertyInfo propInfo = obj.GetType().GetProperty("Items"); //this returns null object itemValue = propInfo.GetValue(obj, null); Console.WriteLine(itemValue); // Does not print out NULL - prints out System.Collections.Generic.List`1[System.Int32] IList values = (IList)itemValue; foreach(var val in values) Console.WriteLine(val); // Writes out values appropriately } } 

@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); } } 

像这样的东西应该做的伎俩:

 var foo = new Foo(); foo.Items = new List(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); } 

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

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

您可以在C#Online Rexter Tool Compiler上查看此代码

 using System; using System.Reflection; namespace GenericPropertyExample { //Declaring a Sample Class public class class1 { public string prop1 { get; set; } public string prop2 { get; set; } } public class Program { public static void Main(string[] args) { //Creating Class Object class1 objClass1 = new class1 { prop1 = "value1", prop2 = "value2" }; //Passing Class Object to GenericPropertyFinder Class GenericPropertyFinder objGenericPropertyFinder = new GenericPropertyFinder(); objGenericPropertyFinder.PrintTModelPropertyAndValue(objClass1); Console.ReadLine(); } //Declaring a Generic Handler Class which will actually give Property Name,Value for any given class. public class GenericPropertyFinder where TModel : class { public void PrintTModelPropertyAndValue(TModel tmodelObj) { //Getting Type of Generic Class Model Type tModelType = tmodelObj.GetType(); //We will be defining a PropertyInfo Object which contains details about the class property PropertyInfo[] arrayPropertyInfos = tModelType.GetProperties(); //Now we will loop in all properties one by one to get value foreach (PropertyInfo property in arrayPropertyInfos) { Console.WriteLine("Name of Property is\t:\t" + property.Name); Console.WriteLine("Value of Property is\t:\t" + property.GetValue(tmodelObj).ToString()); Console.WriteLine(Environment.NewLine); } } } } }