将一些属性复制到新构造函数中

时间:2016-05-12 10:12:51

标签: c# casting

我有一个有很多属性的大班(BigClass)。我需要创建一个只有部分属性的新类(SmallClass)。此SmallClass必须使用BigClass中的所有重叠属性。最简单的方法是什么,而不必像{I>}那样在SmallClass的构造函数中手动分配所有属性:

class BigClass
{
    public int A { get; }
    public int B { get; }
    public int C { get; }
    public int D { get; }
    public int E { get; }

    public BigClass(int a, int b, int c, int d, int e)
    {
        A = a;
        B = b;
        C = c;
        D = d;
        E = e;
    }
}

class SmallClass
{
    public int A { get; }
    public int B { get; }
    public int C { get; }

    public SmallClass(BigClass bigClass)
    {
        // I don't want to do all this manually:
        A = bigClass.A;
        B = bigClass.B;
        C = bigClass.C;
    }
}

1 个答案:

答案 0 :(得分:0)

创建一个帮助类:

public class Helper
{
    public static void CopyItem<T>(BigClass 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);
        }
    }
}

然后在你的SmallClass构造函数中:

public SmallClass(BigClass bigClass)
{
    Helper.CopyItem(bigClass, this);
}

即使您只有财产吸气剂,这也应该有效。

您可以通过更改声明来使CopyItem适用于所有类型;

public static void CopyItem<U, T>(U source, T target)