2016-05-08 33 views
5

例如,我有一個不變的類型不可變類型的對象初始化語法

class Contact 
{ 
    // Read-only properties. 
    public string Name { get; } 
    public string Address { get; } 
} 

,我希望我可以使用對象初始化語法來創建聯繫

Contact a = new Contact { Name = "John", Address = "23 Tennis RD" }; 

但我不能。在這種情況下使用強大的對象初始值設定語法的任何可能的方法?

回答

4

最接近的將是帶有可選參數的構造函數:

class Contact 
{ 
    public string Name { get; } 
    public string Address { get; } 
    public Contact(string name = null, string address = null) { 
     Name = name; 
     Address = address; 
    } 
} 

然後你就可以帶參數的名字稱呼它:

new Contact(
    name: "John", 
    address: "23 Tennis RD" 
) 

的語法是從一個對象初始化略有不同,但它的就像可讀性一樣;和國際海事組織,差異是一件好事,因爲構造參數傾向於建議不變的屬性。而且你可以按任意順序指定參數,或者省去一些參數,所以它和對象初始化語法一樣強大。

這確實需要一些額外的代碼(定義構造函數,分配所有屬性),所以它比對象初始化器語法更多的工作。但不是太可怕,而不可變對象的價值是值得的。

(對於它的價值,C#7可能會immutable "record types"有更簡單的語法,這些可能會或可能不會使它成爲最終版本,但他們的聲音很冷靜。)

0

對象初始化器將首先構造對象,然後設置屬性值。 它需要setter。

它是短手:

Contact a = new Contact(); 
a.Name = "John"; 
a.Address = "23 Tennis RD"; 

的只讀域不能有它一旦對象已經構建設定值。爲了讓該類不可變,您需要創建一個構造函數來獲取這些值:

class Contact // Immutable class 
{ 
    // Read-only properties. 
    public string Name { get; } 
    public string Address { get; } 
    public Contact(string name, string address) 
    { 
     this.Name = name; 
     this.Address = address; 
    } 
} 
+0

我需要制定者 - 都能跟得上它不!它要求在現場寫入訪問或propery。在屬性的情況下它確實需要一個setter。在字段的情況下,它不能是靜態的或只讀的。 –

+0

正確。我之所以說:「然後設置屬性值,需要setter」。即使使用公共setter,如果後臺字段是隻讀的,試圖寫入它也不會編譯。 –

1

不,您不能將其與只讀屬性一起使用。
以下是比較中的不同屬性和字段類型。

public class sometype { 
    public int readonlyProp{ 
     get; 
    } 
    public int normalProp { 
     get; 
     set; 
    } 

    public const int constField = 3; 
    public readonly int readonlyField = 3; 
    public int normalField = 3; 

    public void test() { 
     sometype test = new sometype() { readonlyProp = 3}; //  Doesn't work -> Property or indexer is readonly 
     sometype test1 = new sometype() { normalProp = 3 }; //  ok 
     sometype test2 = new sometype() { constField = 3 }; //  Doesn't work -> Static field or property 
     sometype test3 = new sometype() { readonlyField = 3 }; // Doesn't work -> readonly field 
     sometype test4 = new sometype() { normalField = 3 }; //  ok 
    } 
} 

理解const字段被認爲是靜態的,因此不是實例成員是很重要的。並且由於對象初始值設定項用於實例成員,所以這不起作用。