2013-02-07 145 views
22

這似乎是很愚蠢的和基本的問題,但我試圖谷歌,但也沒有找到滿意的答案,最好的方式來創建對象

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public Person(){} 
    public Person(string name, int age) 
    { 
     Name = name; 
     Age = age; 
    } 
    //Other properties, methods, events... 
} 

我的問題是,如果我有一個類這,創建一個對象的最佳方式是什麼?

Person p=new Person("abc",15) 

OR

Person p=new Person(); 
p.Name="abc"; 
p.Age=15; 

的是這兩個方法,什麼是創建對象的最佳方式之間的區別?

+6

只是第三選擇加進來:'Person p = new Person {Name =「abc」,Age = 15};' - 或第四個:'Person p = new Person(name:「abc」,age:15);'。正如X.L.Ant所說:沒有一個會自動「更好」 –

回答

31

確定是否需要一個不變對象與否。

如果您將public屬性放入您的類中,則可以在代碼中隨時更改每個實例的狀態。所以,你的類可以是這樣的:

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public Person(){} 
    public Person(string name, int age) 
    { 
     Name = name; 
     Age = age; 
    } 
    //Other properties, methods, events... 
} 

在這種情況下,具有Person(string name, int age)構造不是那麼有用。

第二個選項是實現不可變的類型。例如:

public class Person 
{ 
    public string Name { get; private set; } 
    public int Age { get; private set; } 

    public Person(string name, int age) 
    { 
     Name = name; 
     Age = age; 
    } 
    //Other properties, methods, events... 
} 

現在你有一個構造函數設置狀態的情況下,一旦,在創建時。請注意,現在屬性的setter是private,因此在對象實例化後您無法更改狀態。

最好的做法是將類定義爲每次都不可變的時候。要了解不可變類的優點,我建議你閱讀這個article

+1

你的不可變類應該有公共getter和私人setter。 – Servy

+0

@Servy對!我更新了我的答案 – davioooh

+0

從C#6開始,您還可以完全刪除setters以創建只讀屬性。這實際上可以保證你不會意外修改構造函數之外的屬性。 – Kyle

6

這並不是最好的方法。兩者都是相同的,除非你想在初始化期間使用傳遞給構造函數的參數做一些額外的處理,或者如果你想在調用構造函數後確保一致的狀態。如果是這樣的話,更喜歡第一個。

但是出於可讀性/可維護性原因,避免創建具有太多參數的構造函數。

在這種情況下,兩者都可以。

+1

如果它們不需要構造函數中的參數,那麼也更容易測試類。 – timmy

9

真的取決於你的要求,雖然最近我看到了一個類的定義至少有一個裸構造函數的趨勢。

在via構造函數中發佈參數的好處是,您知道這些值可以在實例化後依賴。缺點是你需要更多的工作來處理任何期望能夠用一個單純的構造函數創建對象的庫。

我個人的偏好是使用一個空的構造函數,並將任何屬性設置爲聲明的一部分。

Person p=new Person() 
{ 
    Name = "Han Solo", 
    Age = 39 
}; 

這得到各地的「類缺乏裸構造」的問題,再加上降低了維護(我可以設置更多的事情,而不改變構造函數)。

+0

是否有可能使用類似上面的構造函數,但在聲明後仍然對值做些什麼?目前我在程序中的任何地方都使用這種類型的構造函數,但現在我需要添加額外的構造函數邏輯(使用其中一個參數) - 主要監督。 – Sinjai

4

如果您認爲較少的代碼意味着更高效,那麼使用構造函數更好。 您還可以使用如下代碼:

Person p=new Person(){ 
Name='abc', 
Age=15 
} 
6

在我的愚見,這僅僅是一個,如果參數都是可選與否決定的事情。如果一個Person對象不應該(在邏輯上)沒有名稱和年齡而存在,則它們在構造函數中應該是強制的。如果它們是可選的(即它們的缺席不會對物體的良好功能造成威脅),請使用設置器。

下面是從的Symfony的文檔在構造函數注入報價:

有幾個優點,使用構造器注入:

  • 如果相關性是一個要求和類不能沒有那麼其注入工作它通過構造函數確保當類被使用時它存在,因爲沒有它就不能構造類。
  • 創建對象時,構造函數只會被調用一次,因此您可以確定該對象的生命週期中依賴項不會更改。

這些優點確實意味着構造函數注入不適合使用可選的依賴項。與類層次結合使用也更加困難:如果一個類使用構造函數注入,那麼擴展它並覆蓋構造函數就會產生問題。

(Symfony的是最流行和推崇的PHP框架之一)

0

或者您可以使用數據文件將多個人物件放入列表或數組中。你確實需要爲此使用System.IO。而且你需要一個包含所有對象信息的數據文件。

一種方法,它會是這個樣子:

static void ReadFile() 
{ 
    using(StreamWriter writer = new StreamWriter(@"Data.csv")) 
    { 
     string line = null; 
     line = reader.ReadLine(); 
     while(null!= (line = reader.ReadLine()) 
       { 
        string[] values = line.Split(','); 
        string name = values[0]; 
        int age = int.Parse(values[1]); 
       } 
     Person person = new Person(name, age); 
    } 
} 
0

取決於你的需求量的,而是創造最有效的方法是:

Product obj = new Product 
      { 
       ID = 21, 
       Price = 200, 
       Category = "XY", 
       Name = "SKR", 
      }; 
相關問題