2013-10-22 190 views
0

我從某處獲取類AAA的對象,我想在該對象中添加更多信息。所以,我正在創建一個從AAA派生的新類BBB。 BBB類具有附加的字段字典。我在派生類構造函數中填充此字典,該構造函數採用類AAA對象和我想用作字典鍵的項目數組,並且此字典的值是類AAA對象字段的元素。我試圖在吹示例代碼中創建類似的場景:擴展類的初始化?

void Main(){  
    A obj = new A() ; 
    obj.prop1 = new int [] {5 ,10, 15} ; 
    obj.prop2 = "Hello" ; 
    obj.prop3 = "World" ; 
// obj.Dump() ; 
    B obj2 = new B (new int [] {1,2,3}, obj) ;  
// obj2.Dump() ; 

} 

// Define other methods and classes here 
public class A { 
    public int [] prop1 ; 
    public string prop2 ; 
    public string prop3 ; 
} 

public class B : A { 
    public Dictionary <int, int> prop4 ; 
    public B (int [] keys, A a) { 
    prop4 = new Dictionary <int, int>() ; 
     if (keys.Length == a.prop1.Length) { 
      for (int i = 0 ; i < keys.Length ; i++) { 
       prop4.Add (keys[i], a.prop1[i]) ; 
      } 
      // is there a way to obsolete below lines of code??? 
      this.prop1 = a.prop1 ; 
      this.prop2 = a.prop2 ; 
      this.prop3 = a.prop3 ; 
     } 
     else { 
      throw new Exception ("something wrong") ; 
     }   
    } 
} 

在派生類構造函數中,我手動填充屬性,我不想這樣做。有沒有另一種方式來做到這一點。我在我的實際班級中擁有超過20個物業。

+0

似乎更像你想要一個索引呢?它看起來像你想通過鍵訪問整型數組中的值 - 你能解釋一下用例嗎?一旦你完成了這一次,你已經做到了 - 你計劃與其他物體一起做這一百萬次? – Charleh

+2

「prop1」,「prop2」,「prop3」和「prop4」的名字都很差。它們不代表相同的類型,也不以相同的方式使用。因此,如果您給他們的名稱更清楚地表明瞭它們的用途,那將會非常有幫助。 –

+0

我想添加索引鍵不索引。 – User1551892

回答

2

不能做你問什麼,但我會建議創建A類的拷貝構造函數和使用它與你的類B構造:

// Define other methods and classes here 
public class A 
{ 
    public int[] prop1; 
    public string prop2; 
    public string prop3; 

    public A() 
    { 
    } 

    public A(A orig) 
    { 
     prop1 = orig.prop1; 
     prop2 = orig.prop2; 
     prop3 = orig.prop3; 
    } 
} 

public class B : A 
{ 
    public Dictionary<int, int> prop4; 

    public B(int[] keys, A a) : base(a) 
    { 
     prop4 = new Dictionary<int, int>(); 

     if (keys.Length == prop1.Length) 
     { 
      for (int i = 0; i < keys.Length; i++) 
      { 
       prop4.Add(keys[i], prop1[i]); 
      } 
     } 
     else 
     { 
      throw new Exception("something wrong"); 
     } 
    } 
} 
+0

乾淨的實施沒有副作用。可愛。 – Gusdor

+0

我感謝你的努力,但我不想修改我的基類實現。 – User1551892

+1

@ User1551892不想或不可以?簡單的修改幾乎總是比在解決方法中進行黑客更好!這種特殊的解決方法只涉及一個新的構造函數,僅此而已。 – Gusdor

0

B(您正在構建)的實例和A(您傳遞給B的構造函數)的實例不相關 - 它們具有不同的數據,它們位於不同的內存地址上。通過A的值更新B實例的屬性/字段的唯一方法是複製。

0

Hmmmmmmm ......它有點不清,混淆你最多不過看看這個:

也許它沒有涉及到你所需要的,但至少它可能會給你一個想法。

這是如何從一個類型的所有屬性創建一個字典。

public static Dictionary<string, object> DictionaryFromType(object atype) 
{ 
    if (atype == null) return new Dictionary<string, object>(); 
    Type t = atype.GetType(); 
    PropertyInfo[] props = t.GetProperties(); 
    Dictionary<string, object> dict = new Dictionary<string, object>(); 
    foreach (PropertyInfo prp in props) 
    { 
     object value = prp.GetValue(atype, new object[]{}); 
     dict.Add(prp.Name, value); 
    } 
    return dict; 
} 

可以幫助你。如果不讓我知道刪除這個問題。

0

您在這裏執行的操作與copy constructor非常相似。手工操作是我害怕的唯一方式!

我的建議是使用類的定義Properties和替換的屬性爲您的B類實現:

// Define other methods and classes here 
public class A 
{ 
    public virtual int[] prop1 { get; set; } 
    public virtual string prop2 { get; set; } 
    public virtual string prop3 { get; set; } 
} 

public class B : A 
{ 
    public Dictionary<int, int> prop4; 

    public override int[] prop1 
    { 
     get 
     { 
      return m_WrappedAInstance.prop1; 
     } 
     set 
     { 
      m_WrappedAInstance.prop1 = value; 
     } 
    } 

    public override string prop2 
    { 
     get 
     { 
      return m_WrappedAInstance.prop2; 
     } 
     set 
     { 
      m_WrappedAInstance.prop2 = value; 
     } 
    } 

    public override string prop3 
    { 
     get 
     { 
      return m_WrappedAInstance.prop3; 
     } 
     set 
     { 
      m_WrappedAInstance.prop3 = value; 
     } 
    } 

    A m_WrappedAInstance = null; 
    public B(int[] keys, A a) 
    { 
     m_WrappedAInstance = a; 
     prop4 = new Dictionary<int, int>(); 
     if (keys.Length == a.prop1.Length) 
     { 
      for (int i = 0; i < keys.Length; i++) 
      { 
       prop4.Add(keys[i], a.prop1[i]); 
      } 
     } 
     else 
     { 
      throw new Exception("something wrong"); 
     } 
    } 
} 

功能,這將採取類似行動。唯一的缺點是你的包裝類A實例不能再獨立於你的類B實例進行更改。這是一個要求嗎?

+1

一些需要注意的是深層複製和淺層複製 - 我的意思是你想要引用指向相同的實例嗎?這可能是一場噩夢,取決於需要複製的課程 - 只是認爲我會在 – Charleh

+0

@Charleh中值得考慮 - 這就是爲什麼我總是主張在可以的時候用手去做。一旦進入「自動深度複製」,代碼庫變得複雜。我通常編寫一個深層的副本:D – Gusdor

+1

Aye,但這取決於可序列化的東西 - 我不認爲我真的*需要*編寫一個拷貝構造函數,而不是.NET。總是一個更好的方式來處理這樣的事情 – Charleh

0

定義的數組。再投的項目在數組中的各個屬性

在B類的

public object[] properties; 

public int[] prop1 { 
    get { return (int[]) properties[0]; } 
    set { properties[0] = value; } } 

public string prop2 { 
    get { return (string)properties[1]; } 
    set { properties[1] = value ; } } 

構造

public B (int[] keys, A obj) 
    { 
     properties = A.properties; 
    }