2010-03-10 134 views
1

要使類實例正常工作,應該正確初始化一些字段,初始化這些字段的策略是什麼,應該通過構造函數給出什麼,應該通過屬性給出什麼?c中的實例初始化策略#

我的困惑是,如果構造函數需要一個長參數列表,很難使用,如果通過屬性,我傾向於忘記設置一些屬性。

最佳做法是什麼?

+0

有時,當你發現構造函數列表很長時,類(類型)做得太多了。當然,有時它是不可避免的... – 2010-03-10 04:57:55

回答

2

你必須問自己,如果你的課程需要創造許多東西,也許它做得太多。這是一個跡象,你應該重新考慮你的設計,或者說構造函數在做什麼「工作」。

確實,你不應該能夠創建一個無效狀態的實例;因此構造函數應該把你需要的所有屬性設爲一個有效的狀態。

在某種程度上,它取決於你的模型。例如,我使用的ORM具有構造函數帶一個參數;它可以加載所有其他屬性的ID。如果我必須全部通過它們(這真的是ORM的工作;設置這個對象),這會很麻煩。所以從這個意義上說,你可以說你有一個「無效」對象(沒有屬性設置)。但你會錯的;你實際上有一個「空白」或「空」的對象。這不同於無效。

因此,仔細想想它是什麼意思是你的對象是「無效的」。如果其他方法使用這個對象,我會認爲它是無效的,並且因爲沒有設置某個東西而拋出異常。使用這個邏輯來確定構造函數中需要什麼,以及稍後可以設置什麼(通過其他進程)。

2

這總是一種平衡行爲 - 您不希望具有需要許多參數的構造函數,但也不希望用戶在對象處於有效狀態之前設置許多屬性。不幸的是,這裏沒有真正的指導,因爲您必須對當前的情況做出最佳判斷。

很多時候,您可能需要創建一個具有許多屬性和許多可能配置的複合類型(例如System.Web.Page)。複合類型往往具有簡單的構造函數,只需很少的參數或不需要參數,而且所有的值都必須通過屬性來設置複合類型是由較低級別分解(或簡單)類型組成的高級類型。

外部類型往往更簡單,包含更少的狀態,並且可以通過它們的構造函數完全初始化。因子類型的例子是System.StringSystem.Int32。這些類型非常簡單,並且往往是複合類型的構建塊。

如果您的類型是因式分類,那麼儘量讓消費者通過構造函數完全初始化類型。如果你的類型是一個複合類型,那麼最好提供一些參數很少或沒有的簡單構造函數,並要求消費者通過屬性設置器來配置實例。

+1

+1。我將指出,在「複合類型」的情況下,您需要定義一個定義良好的合同,確定必須設置哪些屬性才能爲實例指定其狀態。記下它的地獄。這樣,一年下來,該對象不會受到可怕的配置:) – Kivin 2010-03-10 05:18:31

+0

@Kivin - 絕對! – 2010-03-10 05:19:21

1

現在,.NET 3.5允許您在創建時設置任何屬性,我通常將任何具有參數的構造函數限制在實例絕對必須具有創建值的情況下。實際上沒有任何其他理由使用參數IMO添加構造函數重載。

1

我認爲最好的辦法是進行驗證,一般儘量保持構造不帶參數,因爲它往往是不同的.NET庫的要求。

通過驗證,您將不得不檢查對象的有效性,但這是很常見的事情。線之間的東西:

public interface IValidateable { 
    IEnumerable<string> Validate(); 
} 

public class Person : IValidateable { 
    public string Title { get; set; } 
    public string First { get; set; } 
    public string Last { get; set; } 
    public Address HomeAddress { get; set; } 

    public Person() { 
     HomeAddress = new Address(); 
    } 


    public IEnumerable<string> Validate() { 
     var errors = new List<string>(); 
     if (string.IsNullOrEmpty(First)) 
     errors.Add("First name is required."); 
     // And so on... 
     return errors; 
    }  
} 

// Usage 
var p1 = new Person(); 
var p2 = new Person { 
    First = "Dmitriy" 
    }; 

if (p1.Validate().Any()) { 
    // Do something with invalid object 
} 
+0

如果班級不是商務班,可能我應該去檢查和提出例外。 – Benny 2010-03-10 05:04:41

+0

是的,這是另一種選擇。 – 2010-03-10 05:18:16