2016-05-12 39 views
2

我有一個有很多屬性的大類(BigClass)。我需要創建一個新類(SmallClass),只有其中一些屬性。此SmallClass必須使用BigClass中的所有重疊屬性。什麼是做到這一點,而不必在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; 
    } 
} 
+3

你需要這樣做嗎?比如'BigClass'是否可以繼承'SmallClass'?如果不是,並且您使用反射等進行循環,那麼如果'BigClass'和'SmallClass'無意中獲得了相同的屬性名稱,但用於完全不相關的目的,那麼長遠來看會發生什麼? –

+2

請看http://automapper.org/ – Lucian

+0

我也是AutoMapper的粉絲,也是 –

回答

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); 
     } 
    } 
} 

然後在你的小類構造:

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

即使您只有屬性獲得者,這也應該有效。

您可以通過更改其聲明使CopyItem與所有類型一起使用;

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