2016-05-12 2 views
2

私は多くのプロパティ()を持つ大きなクラスを持っています。私は新しいクラス(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) 
関連する問題