2008-12-04 40 views

回答

49

錯誤:屬性或索引器不可能會作爲傳出或引用參數

傳遞如果沒有指定{get; set;}那麼編譯器將不知道這是否是一個字段或屬性。 這很重要,因爲當它們「看起來」相同時,編譯器會以不同的方式處理它們。例如在屬性上調用「InitAnInt」會引發錯誤。

class Test 
{ 
    public int n; 
    public int i { get; set; } 
    public void InitAnInt(out int p) 
    { 
     p = 100; 
    } 
    public Test() 
    { 
     InitAnInt(out n); // This is OK 
     InitAnInt(out i); // ERROR: A property or indexer may not be passed 
          // as an out or ref parameter 
    } 
} 

你不應該創建公共字段/於類變量,你永遠不知道什麼時候你會想改變它有讓&組訪問,然後你不知道你要什麼碼打破,特別是如果你有客戶對您的API進行編程。

另外,您可以爲get &集合設置不同的訪問修飾符,例如, {得到; private set;}使get public和set爲private聲明類。

62

因爲你可能需要一個只讀屬性:

public int Foo { get; private set; } 

或者只寫屬性:

public int Foo { private get; set; } 
+3

您還可以添加各種修飾符,如受保護等。 – Tigraine 2008-12-04 13:15:42

+0

是的,還有其他人說的......您需要一種方法來區分字段和屬性。 – 2008-12-04 13:19:50

+1

有點旁註:有隻讀字段的概念。該框架將確保這些只寫入一次。它與私人制片人或獲得者不同,如果你有權限的話可以寫出來。 – 2008-12-04 13:24:38

4

編譯器需要知道,如果你想讓它生成getter和/或一個二傳手,或者可能正在宣佈一個領域。

16

因爲你需要一些方法來區分它與普通的領域。

具有不同訪問修飾符也是有用的,例如,

public int MyProperty { get; private set; } 
2

如果該屬性沒有訪問器,編譯器如何將它與字段分開?什麼將它與田地分開?

16

只是想我會分享我對這個主題的發現。

編碼屬性如下,是一個.net 3.0快捷方式調用「自動執行的屬性」。

public int MyProperty { get; set; } 

這可以爲您節省一些打字費用。申報財產的很長的路是這樣的:

private int myProperty; 
public int MyProperty 
{ 
    get { return myProperty; } 
    set { myProperty = value; } 
} 

當您使用「自動實現的屬性」,編譯器生成的代碼線了get和set一些「k_BackingField」。下面是使用反射器的反彙編代碼。

public int MyProperty 
{ 
    [CompilerGenerated] 
    get 
    { 
     return this.<MyProperty>k__BackingField; 
    } 
    [CompilerGenerated] 
    set 
    { 
     this.<MyProperty>k__BackingField = value; 
    } 
} 

拆卸C#代碼從IL

另外導線開setter和getter的方法。

[CompilerGenerated] 
public void set_MyProperty(int value) 
{ 
    this.<MyProperty>k__BackingField = value; 
} 
[CompilerGenerated] 
public int get_MyProperty() 
{ 
    return this.<MyProperty>k__BackingField; 
} 

從IL拆卸C#代碼

在聲明只讀自動實現的屬性,通過設置器,以私人:

public int MyProperty { get; private set; } 

所有的編譯器標誌「 「作爲私人。 setter和getter方法也是一樣的。

public int MyProperty 
{ 
    [CompilerGenerated] 
    get 
    { 
     return this.<MyProperty>k__BackingField; 
    } 
    private [CompilerGenerated] 
    set 
    { 
     this.<MyProperty>k__BackingField = value; 
    } 
} 

從IL拆卸C#代碼

所以我不知道爲什麼需要框架將Get;並設置;在自動實施的財產上。如果沒有提供set和setter方法,他們可能就沒有寫過。但是,我不知道,可能會有一些編譯器級別的問題讓我感到困難。

如果你看一下聲明只讀屬性的很長的路要走:

public int myProperty = 0; 
public int MyProperty 
{ 
    get { return myProperty; } 
} 

再看看反彙編代碼。二傳手根本就沒有。

public int Test2 
{ 
    get 
    { 
     return this._test; 
    } 
} 

public int get_Test2() 
{ 
    return this._test; 
} 

拆卸C#從IL

2

好代碼,顯然,你需要字段和屬性之間的多義性的一種方式。但是必需的關鍵字是否真的有必要例如,很明顯,這兩個聲明是不同的:

public int Foo; 
public int Bar { } 

這可以工作。也就是說,這是編譯器可以想象的一種語法。

但是,你會遇到空塊具有語義含義的情況。這似乎不穩定。

2

由於沒有人提到它...你可以做自動虛擬財產和重寫它:

public virtual int Property { get; set; } 

如果沒有的get/set,如何將它被覆蓋?請注意,您被允許override the getter and not the setter

public override int Property { get { return int.MinValue; } } 
2

而且,因爲自從C#6.0(在Visual Studio 2015年,在這個答案在版本最終預覽可用時),你可以實現一個真正的只讀屬性:

public string Name { get; } 
public string Name { get; } = "This won't change even internally"; 

...相對於目前的解決方法不完善與公共的吸氣/私人設定器對:

public string Name { get; private set; } 

public Constructor() { Name="As initialised"; } 
public void Method() { Name="This might be changed internally. By mistake. Or not."; } 

低於上述實施例(編譯和executa ble online here)。

using System; 

public class Propertier { 
    public string ReadOnlyPlease { get; private set; } 

    public Propertier() { ReadOnlyPlease="As initialised"; } 
    public void Method() { ReadOnlyPlease="This might be changed internally"; } 
    public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); } 
} 

public class Program { 
    static void Main() { 
     Propertier p=new Propertier(); 
     Console.WriteLine(p); 

//  p.ReadOnlyPlease="Changing externally!"; 
//  Console.WriteLine(p); 

     // error CS0272: The property or indexer `Propertier.ReadOnlyPlease' cannot be used in this context because the set accessor is inaccessible 
     // That's good and intended. 

     // But... 
     p.Method(); 
     Console.WriteLine(p); 
    } 
} 

其他有關C#6的好消息。0可作爲官方預覽視頻here

相關問題