2010-01-02 13 views
0

我覺得有沒有好的答案,但之前我認輸做這個優雅的,我會在這裏問:C#memberwisecopy和後代

我有擁有一組數據的父類。這些僅用於實例化派生父項的後代,修改它併產生最終結果。

我看到如何使用MemberwiseCopy來製作父級的另一個實例,但我需要一個孩子,而不是另一個父級。

我看到兩個答案,這兩者都不喜歡:

1)忘記繼承,使母公司的副本在野外工作副本。

2)將每個字段複製到孩子。

回答

1

使用反射和自定義屬性也許?裝飾您希望複製到後代的字段,並在實例化過程中使用反射遍歷每個裝飾字段並將其值複製到後代。

實施例:

[AttributeUsage(AttributeTargets.Field)] 
class PassDownAttribute : Attribute 
{ 
} 

public class TheParent 
{ 
    [PassDown] 
    public int field1; 
    [PassDown] 
    public string field2; 
    [PassDown] 
    public double field3; 

    public int field4; // Won't pass down. 

    public TheChild CreateChild() 
    { 
     TheChild x = new TheChild(); 
     var fields = typeof(TheParent).GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); 
     foreach (var field in fields) 
     { 
      var attributes = field.GetCustomAttributes(typeof(PassDownAttribute), true); 
      if (attributes.Length == 0) continue; 
      var sourceValue = field.GetValue(this); 
      var targetField = typeof(TheChild).GetField(field.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); 
      if (targetField != null) 
       targetField.SetValue(x, sourceValue); 
     } 
     return x; 
    } 
} 

public class TheChild 
{ 
    public int field1; 
    public string field2; 
    public double field3; 
} 

和使用:

public void TestIt() 
{ 
    TheParent p = new TheParent 
    { 
     field1 = 5, 
     field2 = "foo", 
     field3 = 4.5, 
     field4 = 3 
    }; 
    TheChild c = p.CreateChild(); 
    Debug.Assert(c.field1 == p.field1); 
    Debug.Assert(c.field2 == p.field2); 
    Debug.Assert(c.field3 == p.field3); 
}