System.Reflection-如何调用子级别Types的getter方法
本文关键字:Types 方法 getter Reflection- 何调用 调用 System | 更新日期: 2023-09-27 18:23:59
我有三个类:
public class TestA
{
public string Str1 { get; set; }
public string Str2 { get; set; }
public TestB TestB { get; set; }
public TestA()
{
Str1 = "string1";
Str2 = "string2";
TestB = new TestB();
}
}
public class TestB
{
public string Str3 { get; set; }
public string Str4 { get; set; }
public TestC ObjTestC { get; set; }
public TestB()
{
Str3 = "string3";
Str4 = "string4";
ObjTestC = new TestC();
}
}
public class TestC
{
public string Str5 { get; set; }
public TestC()
{
Str5 = "string5";
}
}
现在,我已经获得了所有的PropertyInfo并创建了一个新对象:
//Get all the properties
var prop = typeof(TestA).GetProperties();
for (int i = 0; i < prop.Count(); i++)
{
var propertyInfo = prop[i];
if (propertyInfo.PropertyType.Namespace != "System")
{
if (propertyInfo.PropertyType.IsGenericType &&
propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
Type itemType = propertyInfo.PropertyType.GetGenericArguments()[0]; // use this...
var listObjectProperties = itemType.GetProperties();
prop = prop.Union(listObjectProperties).ToArray();
}
else
{
var childProp = propertyInfo.PropertyType.GetProperties();
prop = prop.Union(childProp).ToArray();
}
}
}
//Create Object
TestA testA = new TestA();
现在,我需要的是调用每个属性的getter方法。我尝试了以下操作,它调用TestA类属性的getter。但是,当试图调用TestB和TestC:中属性的getter时,它会抛出错误
// Loop through all properties
foreach (PropertyInfo propertyInfo in prop)
{
MethodInfo getterMethodInfo = propertyInfo.GetGetMethod();
var obj=getterMethodInfo.Invoke(testA, null);
}
请帮忙。。。
提前感谢
检查此代码,我希望prop
数组包含TestA
和TestB
上的所有属性,并且根本不涉及TestC
:
// Gets TestA's properties...
var prop = typeof(TestA).GetProperties();
// Then gets TestB's properties...
var childProp = propertyInfo.PropertyType.GetProperties();
prop = prop.Union(childProp).ToArray();
如果你想从这三种类型中获取属性,你可能应该递归地进行。您不希望每次稍微更改这些对象的结构时都必须修改此循环。
但这并不是真正的问题。
真正的问题是,针对TestB
的属性调用getterMethodInfo.Invoke(testA, null)
,但传递了TestA
的实例,因此出现了错误。想想如果你不使用反射,你将如何获得这个值。您现有的代码基本上是这样做的:
var value = testA.Str3; // !!! there is no Str3 property on TestA !!!
为了正确工作,您需要这样做:
var value = testA.TestB.Str3;
看看我们是如何调用属性链来获得所需的值的?首先是TestA.TestB
,然后是TestB.Str3
。如果你需要使用反射,那么代码也需要做同样的事情:
var obj = (object)testA;
obj = testBPropOnTestA.GetValue(obj, null);
var value = str3PropOnTestB.GetValue(obj, null);
因此,您不需要在集合中存储PropertyInfo
的简单实例,而是需要存储PropertyInfo
s的列表。
因此,您的最终"获取值"循环看起来更像:
foreach (var propertyChain in prop)
{
var obj = (object)testA;
foreach (var property in propertyChain)
{
obj = property.GetValue(obj, null);
if (obj == null) {
break;
}
}
Console.WriteLine("{0} = {1}",
string.Join(".", propertyChain.Select(x => x.Name)),
obj);
}
我将把如何修复第一个"收集PropertyInfo
s"循环留给您。