简体   繁体   English

如何使用反射来更改缺少setter的属性?

[英]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.

相关问题 使用反射,如何检测具有setter的属性? - Using reflection, how do I detect properties that have setters? 如何将 Bogus 与私人二传手一起使用? - How can I use Bogus with private setters? 如何在单元测试中模拟没有设置器的属性? - How can I mock properties which have no setters in unit testing? 如何使用反射来查找实现特定接口的属性? - How can I use reflection to find the properties which implement a specific interface? 如何使用反射来检索特定类型的所有字段和/或属性? - How can I use reflection to retrieve all the fields and/or properties for a specific Type? 如何使用反射来获取显式实现接口的属性? - How do I use reflection to get properties explicitly implementing an interface? 如何将自定义样式与设置器和触发器一起使用? - How can i use a custom style with setters and triggers? 如何使用反射设置类属性值 - How can I set my class properties values Using Reflection 如何创建一个忽略没有setter的属性的Fluent NHibernate约定 - How can I create a Fluent NHibernate Convention that ignores properties that don't have setters 如何使用反射将一个对象动态转换为另一个对象? - How can I use reflection to dynamically cast one object to another?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM