[英]How can I use reflection to change properties with missing setters?
I have two classes with property getters only 我有两个只有属性getter的类
public class A
{
public A(string name)
{
Name = name;
}
public string Name { get; }
public string Value { get; set;}
public string Data { get; set;}
}
public class B
{
public B(string name)
{
Name = name;
}
public string Name { get; }
public string Value { get; set;}
}
They are different in shape but share some of the same property names and types. 它们的形状不同,但共享一些相同的属性名称和类型。 How can I copy values when they only have getters?
如果只有吸气剂,我怎么能复制价值?
This is a typical scenario when I send an object as a constructor parameter to extract values from in the new object. 这是我将对象作为构造函数参数发送以从新对象中提取值时的典型情况。 Then I need to copy values one by one.
然后我需要逐个复制值。 This can produce lots of code and is hard to maintain.
这可能会产生大量代码并且难以维护。
Can this be made simpler? 这可以变得更简单吗? Is there a way to use reflection to copy objects when the target only has getter properties?
当目标只有getter属性时,有没有办法使用反射来复制对象?
It is possible to create a helper function that copies two objects where the target object only has property getters. 可以创建一个辅助函数来复制目标对象只有属性getter的两个对象。
Try this; 尝试这个;
public static void CopyItem<U, T>(U source, T target)
{
// Need a way to rename the backing-field name to the property Name ("<A>k__BackingField" => "A")
Func<string, string> renameBackingField = key => new string(key.Skip(1).Take(key.IndexOf('>') - 1).ToArray());
// Get public source properties (change BindingFlags if you need to copy private memebers as well)
var sourceProperties = source.GetType().GetProperties().ToDictionary(item => item.Name);
// Get "missing" property setter's backing field
var targetFields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField).ToDictionary(item => renameBackingField(item.Name));
// Copy properties where target name matches the source property name
foreach(var sourceProperty in sourceProperties)
{
if (targetFields.ContainsKey(sourceProperty.Key) == false)
continue; // No match. skip
var sourceValue = sourceProperty.Value.GetValue(source);
targetFields[sourceProperty.Key].SetValue(target, sourceValue);
}
}
This is a generic description. 这是一个通用的描述。 You will probably want to check the property and field data types as well before you copy the value to prevent exceptions.
在复制值以防止异常之前,您可能还需要检查属性和字段数据类型。 Both name and data type should match.
名称和数据类型都应匹配。
Use CopyItem to copy matching source properties in a constructor; 使用CopyItem复制构造函数中的匹配源属性;
public class SomeClass
{
public SomeClass(SomeSourceClass source)
{
Helper.CopyItem(source, this);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.