2012-11-14 27 views
1

假設方案:對象屬性如何知道它的父項?

class ComplexProperty 
{ 
    string PropertyName {get; set;} 
    string Description {get; set;} 
    string GetParentName(); // How can this be implemented? 
} 

class Parent 
{ 
    string ParentName {get; set;} 
    ComplexProperty Property {get; set;} 
} 

的問題是從ComplexProperty內得到ParentName。

我提出的最佳解決方案是使用Parent的構造函數來初始化屬性,但是當您從不同位置設置屬性時,這很容易出現錯誤並失敗。

例如:

class Parent 
{ 
    public Parent() 
    { 
     ComplexProperty = new ComplexProperty(this); // Store an instance of the parent inside the property 
    } 
    string ParentName {get; set;} 
    ComplexProperty Property {get; set;} 
} 

這個任何想法?這種架構有沒有最佳做法?請注意,ComplexProperty將永遠是特定接口實現的孩子,所以反射是一種可行但不是理想的解決方案。

+1

它是否必須有公共二傳手? – Paddy

+0

你能否解釋一下你的意思是「容易出錯,當你從不同的地方設置房產時失敗」? YOu可以考慮修改ComplexProperty來獲得另一個名爲ParentName的屬性,或者可能有一個名爲SetParentName的方法,它可以設置一個本地私有變量。現在在'ComplexProperty Property {get;組; }'你可以修改setter來改變它。 – ryadavilli

+0

'ComplexProperty'必須根據它的上下文(基本上是保存它的項目)收集一些信息並進行計算。例如,它需要獲取字符串屬性的名稱,而不是類的名稱,因此它需要訪問排序實例。 –

回答

1

一種方法可能是保留Parent屬性並將其設置在ComplexProperty設置器中。

class ComplexProperty 
{ 
    public string PropertyName {get; set;} 
    public string Description {get; set;} 
    public IParent Parent {get; set;} 
    public string GetParentName() 
    { 
     return this.Parent == null ? null : this.Parent.Name; 
    } 
} 

interface IParent 
{ 
    string Name {get; set;} 
} 
class Parent : IParent 
{ 
    public string ParentName {get; set;} 

    private ComplexProperty _prop; 
    public ComplexProperty Property 
    { 
     get { return _prop; } 
     set 
     { 
      _prop = value; 
      _prop.Parent = this; 
     } 
    } 
} 
+0

感謝您的答案,更多setter的樣板,但+1,因爲這實際上消除了更改'ComplexProperty'的問題。它仍然是我的解決方案,我不太喜歡,我不知道爲什麼,似乎是錯誤的,因爲某些原因 –

+0

其實我只是注意到你說ComplexProperty將永遠是一個特定接口的孩子,所以Parent屬性應該是該接口類型。更新了我的答案。 –

0

你可以使用一個FUNC

class ComplexProperty 
{ 
    private readonly Func<string> GetParentNameFunc; 

    string PropertyName {get; set;} 
    string Description {get; set;} 
    string GetParentName {get {return GetParentNameFunc(); } } 

    public ComplexProperty(Func<string> GetParentNameFunc) 
    { 
     this.GetParentNameFunc = GetParentNameFunc; 
    } 
} 

class Parent 
{ 
    string Name {get; set;} 
    ComplexProperty Property {get; set;} 

    //... 
    //... 

    SomeMethodOrCtor() 
    { 
     Property = new ComplexProperty(()=>{ return this.Name; }); 
    } 

} 
+0

從存儲整個實例引用,除了更多的代碼之外,這是如何更好? –

+0

獲取父名稱的邏輯保留在父類中,這意味着您可以將ComplexProperties添加到任何類,而無需將該類實現爲特定類型的實現的特定接口。 – wdavo

+0

噢,我明白了,這實際上並不是一個要求,因爲所有的父類都是特定的接口,並且這種強大的屬性耦合意味着在上下文(或複雜屬性)發生變化的情況下進行大量的維護!謝謝你的回答 –

0

你可以使用的EntityFramework,這是basicly作出處理這種關係。但是,它帶來了我不太感激的開銷。只要看看有多少關於這個框架的問題最終在這裏...

或者你也可以編碼自己的。在我所做的一個建模編輯器中,我最終得到了一個組件/實體設置,其中組件需要知道它是父級以瞭解空間位置。組件也可能需要知道包含實體的場景。

使用構造函數是一種方法,但可能不適用於所有內容,因爲您可能不知道父項的標識。

您還可以使用存取器,當您更改屬性時,在您接收的對象中調用類似「SetParent」的東西。

此外,在序列化中,我最終做了重建父母設置,因爲序列化層次結構是矯枉過正。從頂部調用,我將在包含的每個對象中設置父項,然後在所有子項中調用相同項,等等。

當然,你必須假設一個對象只有一個父對象。如果你的整個代碼從一開始就是以這種方式構建的,那麼管理起來並不是很難。

+0

感謝您的回覆。這不需要用ORM做很多事情,但是我仍然使用nHibernate。在我的情況下的開銷將是一個對象工廠,將是唯一的東西產生父類,在這種情況下,我的解決方案將始終工作,因爲ComplexProperty將有一個對父對象的引用(很像EF中的關係映射)! –

相關問題