2014-11-21 29 views
1

我的類有十個屬性,必須先使用該類才能使用該類。如何強制客戶端設置某些屬性

我想在調用任何類的方法之前強制(或者至少非常強烈地鼓勵,最好帶有警告)我的類的用戶設置這些屬性。

我可以使用一個構造函數,它將所有屬性的值作爲參數,但我不想因爲那麼多參數太笨重。

我可以檢查類的所有方法中的屬性值,但這太遲了 - 我想要一個編譯時檢查。

我該怎麼辦?

+9

這恰恰是什麼構造函數。他們讓對象進入一種可用的狀態 - 你不能保證客戶端會或不會調用方法或設置屬性等。如果有很多屬性需要設置,也許這​​個類會嘗試做太多的事情,本身應該分成幾個小類 – 2014-11-21 15:17:45

+0

你可以將你的屬性移動到他們自己的類「PropClass」中。然後讓你的類有一個屬性'PropClass',並在構造函數中使用'PropClass'參數。 – Jonesopolis 2014-11-21 15:17:56

+0

任何其他建議比使用構造函數將使用最醜的解決方案。你能向我們展示你的班級圖表嗎?太多的參數暗示你的班級做得太多。 – SBI 2014-11-21 15:18:13

回答

5

也許你可以使用流利接口的Builder Pattern的一些變化。你可能有某種步驟或者某些你不能跳過某些屬性的東西。例如,要設置的助洗劑的特性y您需要,設置屬性X.

new Builder().SetX(10).SetY(20) //compiles because SetX returns a class with SetY method 
new Builder().SetY(20) //does not compile because the builder only has SetX method 

爲了避免具有多個類由該方法返回的對象可能需要具有多個接口的一個類的每一個公開只有一個方法。

在另一方面,我可能會去的構造,即使有很多的參數

+1

是的,Builder模式很適合這類問題。例如。你有一個內部構造函數的複雜對象。然後你設計其他對象來構建你的對象。例如。稱爲NetPipeFactory的類可能包含創建NetPipe對象(具有複雜配置)的必要方法。或者,也許你有一個名爲Graphics的類,它使用FromImage,FromHnd等等等方法創建自己。 – 2014-11-21 15:38:27

0

一些想法:


可選參數應該減少構造的爛攤子參數

public class SomeClass 
{ 
    public int Property1 {get; private set;} 
    public int Property2 {get; private set;} 
    public int Property3 {get; private set;} 

    public SomeClass(int some1 = 1, int some2 = 2, int some3 = 3) 
    { 
     SomeProperty1 = some1; 
     SomeProperty2 = some2; 
     SomeProperty3 = some3; 
    } 
} 

易於使用:

var a = new SomeClass(some3: 123); 

您可以嘗試使用nullables到throw,如果某個值未設置

public class SomeClass 
{ 
    private int? _property1; 
    public int Property1 { get { return (int)_property1.Value; } } // will throw 

    public SomeClass() {} 

    public int SomeMethod() 
    { 
     int val = _property1.Value; // will throw 
     ... 
     return 123; 
    } 
} 
0

問題具有複雜的構造,是他們往往不解釋意源。例如,假設您有一個可以從字節數組,圖像,句柄,內存地址,base64編碼的字符串或更多等創建的類。

要爲每個人創建構造函數,您不能真正描繪那個。例如。如果一個構造函數接受一個字符串(即使它的參數名是base64String),它也不是很直觀。

一個更好的辦法我遵循複雜的構造是讓我的私人的構造,而是我通過返回它的實例化自我的public static方法暴露我對象的創建。例如,可以使用.Net圖形類。你可以從圖像或窗口句柄等創建圖形類,併爲每個它有方法「FromImage,FromHandle等」。遵循這種模式,在我看來,更直觀,因爲您知道您只是在方法名稱中從圖像創建它,這可以是一個體面的方式來馴服複雜的構造函數和初始化模式。

0

As @Stilgar指出Builder模式是一個很好的答案。根據您希望給予最終用戶的「鼓勵」級別,您可以使用具有默認參數的構造函數。這樣他們將看到他們應該設置的東西(用Intellisense),但也可以選擇他們希望用命名參數設置的東西。

 public ComplexObject(string P1 = "Test", int P2 = 123, double P3 = 3.1415927) 
     { 

     } 

enter image description here

相關問題