2012-01-12 56 views
1

背景: 對其中嵌有多層嵌套形狀的圖形進行圖片處理。性質的變化,例如任何形狀的面積和長度都會導致所有相關的屬性和形狀發生變化。C#與內部設置器的接口

我有一個設計圖案,其是這樣的:

我有稱爲(爲討論起見),其具有噸它們彼此相關的屬性,例如「NestedShapes」一個對象圖,「區」和「長度」。但是圖表被設計爲愚蠢的,即給定任一值,它不知道如何計算另一個值,也不會這樣做。

相反,該圖可以附加到一個GraphManager,它在其構造器中採用頂級根節點IRootShape。

NestedShapes實現了IRootShape,它也實現了INotifyPropertyChanged。 GraphManager訂閱這些屬性更改,並運行邏輯來計算相關字段並通過IRootShape將圖形設置爲正確的狀態。

問題: 隨着IRootShape,我有IShape,ISquare,ICircle等是真正的C#接口。但問題出在這些屬性中的一部分,我只希望它們擁有GraphManager專用的setter。我知道實現形狀仍然可以暴露一個公共setter,但我不希望在UI側公開這些以便能夠從GraphManager中設置屬性。我該怎麼辦?內部基礎類是否需要走?

+1

接口的定義是聲明應該是外部可見的。我敢說,基礎班將是你最好的選擇。 – 2012-01-12 01:32:07

+0

如果你想要所有形狀的共同行爲,那麼他們需要從一個公共基類繼承。另外,爲什麼你需要'ICircle','ISquare'等單獨的接口?爲什麼不只是'IShape'。 – ja72 2012-01-12 02:12:46

+0

@ ja72我想我會說IShape,ISquare,ICircle只有狀態。行爲在GraphManager中。 – Jake 2012-01-12 02:47:22

回答

2

讓GraphManager與基類進行交互。

其他一切只與接口交互。

不要在您的界面中顯示屬性。

public class Circle : ICircle{ 
    public double Radius{ 
     get;set; 
    } 

    /* blah blah ... */ 
} 

public interface ICircle { 
    /* No properties */ 

    /* blah blah ...*/ 
} 
+0

+1。此外,如果需要,您可以將getter移動到界面,但實現將根據需要隨意設置內部/私有設置器。 – 2012-01-12 01:55:33

+0

@Daryl我得到了基類的想法。但我不明白在這種情況下空接口的用途。可以解釋一下嗎? – Jake 2012-01-12 02:49:11

+0

@Jake,它是你的代碼 - 想要與屬性接口 - 添加它們,根本不需要接口 - 不要創建一個接口。 – 2012-01-12 02:59:25

0

通過接口做到這一點的技巧是使用兩個獨立的接口;一個是公共的,一個是內部的。是的,它需要更多的代碼,因爲你必須明確地實現內部接口,手動將它的屬性約定委託給實際屬性,但我只是將它隱藏在名爲'ClassName.Internal.cs'的文件中的部分類中

通過這種方式,您可以清楚而乾淨地以您想要的確切權限公開接口,而無需訴諸基類,因此此技術也可用於擴展現有對象圖。

下面是一個帶有公共getter和內部setter的TestItem的示例,它們都可以通過接口訪問。

這裏的主類文件與公衆接觸,存儲在TestItem.cs

public interface ITestItem 
{ 
    ModelItem Owner { get; } 
    ModelScope Scope { get; } 
} 

public partial class TestItem : ITestItem 
{ 
    // These implicitly handle ITestItem since the getters are public 
    public ModelItem Owner { get; internal set; } 
    public ModelScope Scope { get; internal set; } 
} 

這裏是存儲在通過局部類實現TestItem.Internal.cs僅供內部使用的實現。

internal interface IWritableTestItem 
{ 
    ModelItem Owner { get; set; } 
    ModelScope Scope { get; set; } 
} 

public partial class TestItem : IWritableTestItem 
{ 
    ModelItem IWritableTestItem.Owner 
    { 
     get => Owner; 
     set => Owner = value; 
    } 

    ModelScope IWritableTestItem.Scope 
    { 
     get => Scope; 
     set => Scope = value; 
    } 
} 

希望這會有所幫助!