2014-07-07 21 views
3

我想了解更多關於我偶爾在某些C#代碼中看到的構造;不過,我不知道這個名字。我很抱歉,如果這是重複的;然而,在不知道名字的情況下,很難去尋找東西。new()後的括號是否存在?

的結構如下:

Person me = new Person(){ Name = "Aelphaeis" } ; 

是否有指定這樣的字段/屬性一個特殊的名字?

+6

是的。它被稱爲對象初始值設定項。 –

+2

順便說一句,你可以在使用對象初始值設定項時省略空括號。 – Philippe

回答

8

這叫做對象初始化器。比如讓我們有一個叫做Customer類,其定義下列之一:

public class Customer 
{ 
    public int ID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Age { get; set; } 
} 

然後,你可以實例Customer類型的對象象下面這樣:

Customer customer = new Customer 
{ 
    ID = 0, 
    FirstName="firstName", 
    LastName="lastName", 
    Age = 20 
}; 

幾句話它的另一種方式實例化一個對象。

當我們使用對象初始值設定項時,幕後發生了什麼?

Customer默認的空構造函數:

Customer customer = new Customer(); 

,然後propertie的setter的被調用的順序他們寫的對象初始化

customer.ID = 0; 
customer.FirstName = "firstName"; 
customer.LastName = "lastName"; 
customer.Age = 20; 

而且,一個概念接近對象初始化器colle ction初始化程序

而不是寫這個的:

List<int> numbers = new List<int>(); 
numbers.Add(1); 
numbers.Add(2); 
numbers.Add(3); 
numbers.Add(4); 

我們可以這樣寫:

List<int> numbers = new List<int>() { 1, 2, 3, 4 }; 

這是definetely更緊湊,最初的版本,我也會說更具表現力。在上面的例子中,我們使用了一個集合初始化程序

當我們使用集合初始值設定項時,幕後發生了什麼?

如果我們把最後一個例子,它發生正是這一點:

// Create the a new list 
List<int> numbers = new List<int>(); 

// Add one element after the other, in the order they appear in the 
// collection initializer, using the Add method. 
numbers.Add(1); 
numbers.Add(2); 
numbers.Add(3); 
numbers.Add(4); 

更多有關對象和集合初始化,請訪問該link

最後但並非最不重要,我想指出的是對象和集合初始化程序在C#3.0中引入。不幸的是,如果你不得不在C#2.0的日子裏編寫一個應用程序,那你還沒有這個功能。

+0

A *集合初始化*(您的示例中的一個)和一個*對象初始化*(OP的示例中的一個)不是同一件事。強調兩者之間的差異非常重要。 – dcastro

+0

是的,我現在就做。感謝提到這 – Christos

+0

很好的答案;不過,我認爲可以通過添加菲利普評論的例子來增強未來的查詢。 (新學生姓名{FirstName =「Craig」,姓氏=「Playstead」,ID = 116};) – Aelphaeis

2

這被稱爲對象初始值設定項。對於稱爲集合初始值設定項的集合也有類似的模式。

這是一個基本的例子:

// a constructor that takes an id for a parameter 
var widgetB = new Widget("1") 
{ 
    WidgetId = "1", 
    WidgetName = "My Widget" 
}; 

還有集合初始化器(也可以是用聯合收割機:

var widgetA = new Widget 
{ 
    WidgetId = "1", 
    WidgetName = "My Widget" 
}; 

您也可以同時使用一個對象初始化調用構造函數對象初始值設定項):

var widgetList = new List<Widget> 
    { 
     new Widget {WidgetId = "1", WidgetName = "A"}, 
     new Widget {WidgetId = "2", WidgetName = "B"}, 
     new Widget {WidgetId = "3", WidgetName = "C"}, 
    }; 

您還可以嵌套對象或聚集ction初始化

var widget = new Widget 
{ 
    WidgetId = "1", 
    WidgetName = "My Widget", 
    ChildWidget = new Widget 
    { 
     WidgetId = "2", 
     WidgetName = "I'm a Child Widget" 
    } 
}; 

這種模式也可用於匿名對象:

var anonymousObject = new 
{ 
    Id = "1", 
    Name = "My Anonymous Object", 
}; 

可以使用的濫用在許多方面的模式,但在某一點上它可以開始變得有點難以閱讀。

需要注意的一件重要事情是對象分配是在調用對象構造函數之後進行的。因此,通過對象初始化設置的任何值都不會在構造函數中可用。

延伸閱讀:

+3

我看不出爲什麼這個答案被低估了 –

+0

我認爲這是因爲設置對象的屬性並向列表添加元素是兩件不同的事情?請糾正我,如果我在這裏錯了。 – sekky

+0

好吧,從技術上講,一個被稱爲對象初始值設定項,一個被稱爲集合初始值設定項,但是可以將該點作爲編輯而不是downvote? –

2

這就是所謂的對象初始化。你可以找到更多信息here

您可以集合做同樣的(集合初始化)

List<Cat> cats = new List<Cat> 
{ 
    new Cat(){ Name = "Sylvester", Age=8 }, 
    new Cat(){ Name = "Whiskers", Age=2 }, 
    new Cat(){ Name = "Sasha", Age=14 } 
}; 

就個人而言,我不喜歡它,有兩個原因,

  1. 如果一個例外拋出在對象初始值設定項中,您沒有確切的行號在它發生的地方。我會用它來進行簡單的初始化,但不是用於一些複雜的初始化。
  2. 我覺得很難閱讀(但這是個人喜好)
+1

您對複雜的初始化做出了卓越的貢獻。也就是說,如果異常將會(或者至少應該)發生在正在被初始化的對象的構造函數/被調用的函數中,那麼這種異常更有可能發生,如果它不僅僅是「新」對象的話。 +1進行適當的警告。 –