C# 使用反射查找和更新基于类型的对象
我试图检查嵌套对象中的值,并在必要时替换它们。使用反射,我可以遍历所有嵌套对象并获取属性类型,但我无法检索值并替换值。我举了一个简单的例子 假设我有以下模型:C# 使用反射查找和更新基于类型的对象,c#,reflection,C#,Reflection,我试图检查嵌套对象中的值,并在必要时替换它们。使用反射,我可以遍历所有嵌套对象并获取属性类型,但我无法检索值并替换值。我举了一个简单的例子 假设我有以下模型: public class Employee { #region Members private string _FirstName; private string _LastName; private StreetAddress _EmployeeAddress; #endregion #r
public class Employee
{
#region Members
private string _FirstName;
private string _LastName;
private StreetAddress _EmployeeAddress;
#endregion
#region Properties
public string FirstName { get { return _FirstName; } set { value = _FirstName; } }
public string LastName { get { return _LastName; } set { value = _LastName; } }
public StreetAddress EmployeeAddress { get { return _EmployeeAddress; } set { value = _EmployeeAddress; } }
#endregion
}
public class StreetAddress
{
#region Members
private string _Street;
private string _City;
private string _State;
private string _Zip;
#endregion
#region Properties
public string Street { get { return _Street; } set { value = _Street; } }
public string City { get { return _City; } set { value = _City; } }
public string State { get { return _State; } set { value = _State; } }
public string Zip { get { return _Zip; } set { value = _Zip; } }
#endregion
}
在我的场景中,我需要将StreetAddress中出现的任何对象的StreetAddress从“123 Main Street”更新为“999 Main Street”。StreetAddress对象可以出现在任何给定对象的任何级别。
假设我将Employee强制转换为一个对象,我使用下面的代码遍历Employee对象,查找StreetAddress类型
用法:
ReadPropertiesRecursive2(Employee.GetType());
我不确定在使用1返回值和2更新值(如果需要)的语法中缺少了什么。如果你能给我指出正确的方向,那就太棒了,或者如果有更好的方法,我很想知道。提前谢谢 最大的问题是GetValue需要一个实际对象来获取的值。PropertyInfo,就这一点而言,类型只是元数据。换句话说,GetValue的有效使用如下所示:
Employee emp = new Employee();
PropertyInfo addressProp = typeof(Employee).GetProperty("StreetAddress");
string address = addressProp.GetValue(emp);
传递null将尝试使其脱离静态实例,以获取其价值
重构您的代码以获得并抵消实际实例的影响,您应该不会有问题。您这里的问题是您正在输入一种类型的对象,而不是对象本身 当您将参数提供为
ReadPropertiesRecursive2(Employee.GetType());
您不是提供Employee对象本身,而是提供对象的“类型”。
因此,当您要求它读取这些属性的值时,它会说“读取哪个对象上的属性或字段?”
StreetAddressType.GetProperty("Street").GetValue(StreetAddressType, null);
上面的null必须是您正在处理的实际对象。
将方法签名更改为:
private static void ReadPropertiesRecursive2(Type type, object obj)
然后将保存数据的实际对象作为第二个参数输入
然后,您可能能够执行以下操作:
StreetAddressType.GetProperty("Street").GetValue(StreetAddressType, obj);
现在,您将告诉它读取obj对象上的“Street”字段
如果你能给我指出正确的方向,那就太棒了,或者如果有更好的方法,我很想知道
这个答案更多地属于“指向正确的方向”类别
您似乎希望更新各种实体上的街道地址,这些实体可能在其结构中的某个位置包含StreetAddress实例,可能嵌套了几层
这方面的基本问题是,我们的代码应该编写为与特定类的特定属性交互。我们需要知道要更新哪个属性并更新该属性,而不仅仅是更新任何看起来可能是正确的属性,因为它属于某种类型
考虑这个例子:
public class Employee
{
public StreetAddress Address {get;set;}
public EmergencyContact EmergencyContact {get;set;}
}
public class EmergencyContact
{
public StreetAddress Address {get;set;}
}
如果以正常方式更新地址:
employee.StreetAddress = updatedAddress;
或
那你就没事了
但如果你这样做:
UpdateStreetAddress(object something, "123 Maple St.")
…然后它会查找每个StreetAddress,它会更新该对象中任何位置的每个StreetAddress。它将设置员工的地址和员工的紧急联系人地址
尝试编写一个适用于所有类的一刀切方法是不值得的。最好只编写代码来准确地更新您需要更新的内容。如果代码多一点也没关系,尽管可能不会。你可以通过不处理缺陷、意外的副作用和未来的开发人员不必弄清楚发生了什么来挽回时间。担心这是一个问题,我可以问你为什么需要使用反射来做这件事吗?同意-除非这只是一个了解反射如何工作的实验,几乎可以肯定的是,最好不要使用反射。当你以正常的方式使用你的属性和方法时,当你试图做错事时,你会得到一个编译器错误。这很好,因为它很容易修复。使用反射,您将得到一个运行时错误,因为在程序运行之前,它无法判断什么将工作或什么将不工作。反射在我们需要的时候就在那里,但它不应该是我们在正常情况下使用类的方式。谢谢大家的反馈。似乎我正试图用一个通用解决方案解决一些具体问题,我应该采取更安全、更强类型的路线。我选择反射的原因是当时我的对象类型未知。我感谢大家的意见。
employee.EmergencyContact.StreetAddress = updatedAddress;
UpdateStreetAddress(object something, "123 Maple St.")