如果在C#自動屬性中get和set都是強制的,爲什麼我必須打擾指定「get; set;」在所有?C#自動屬性 - 爲什麼我必須寫「get; set;」?
回答
錯誤:屬性或索引器不可能會作爲傳出或引用參數
傳遞如果沒有指定{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聲明類。
因爲你可能需要一個只讀屬性:
public int Foo { get; private set; }
或者只寫屬性:
public int Foo { private get; set; }
編譯器需要知道,如果你想讓它生成getter和/或一個二傳手,或者可能正在宣佈一個領域。
因爲你需要一些方法來區分它與普通的領域。
具有不同訪問修飾符也是有用的,例如,
public int MyProperty { get; private set; }
如果該屬性沒有訪問器,編譯器如何將它與字段分開?什麼將它與田地分開?
只是想我會分享我對這個主題的發現。
編碼屬性如下,是一個.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
好代碼,顯然,你需要字段和屬性之間的多義性的一種方式。但是必需的關鍵字是否真的有必要例如,很明顯,這兩個聲明是不同的:
public int Foo;
public int Bar { }
這可以工作。也就是說,這是編譯器可以想象的一種語法。
但是,你會遇到空塊具有語義含義的情況。這似乎不穩定。
由於沒有人提到它...你可以做自動虛擬財產和重寫它:
public virtual int Property { get; set; }
如果沒有的get/set,如何將它被覆蓋?請注意,您被允許override the getter and not the setter:
public override int Property { get { return int.MinValue; } }
而且,因爲自從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。
- 1. 爲什麼我必須在屬性上實現set-method?
- 2. 爲什麼自動實現的屬性必須同時定義get和set訪問
- 3. 自動實現的屬性必須同時定義get和set訪問器
- 4. 爲什麼重寫==必須重寫equals?
- 5. 目標屬性必須是依賴屬性 - 爲什麼?
- 6. 什麼時候在C#中使用get和set屬性?
- 7. C#虛擬自動屬性省略get/set
- 8. 爲什麼我們必須提供boost :: get的參數類型?
- 9. 爲什麼我必須在通用類
- 10. 爲什麼必須使用Set來保存對象?
- 11. 爲什麼我必須施放代表?
- 12. 訪問者爲什麼必須比屬性限制更多?
- 13. 自動生成的屬性{get; set;} vs {get;私人或保護集;}在C#
- 14. 在apex中定義get和set的自動屬性有什麼意義?
- 15. 爲什麼我必須使用POST而不是GET?
- 16. 爲什麼我必須調用base.OnAuthorization(filterContext)
- 17. 爲什麼我必須輸入兩次?
- 18. 從Get屬性引用Set屬性
- 19. 爲什麼我必須編譯JavaFX SceneBuilder?
- 20. 爲什麼我必須使用-lstdC++ fs?
- 21. 爲什麼我必須包含索引?
- 22. 爲什麼選擇自動屬性?
- 23. Zend_Db_Table_Row:爲什麼我必須使用createRow()?
- 24. 爲什麼必須N-1在C
- 25. 我們必須在函數「return」的末尾寫什麼?在C++
- 26. 爲什麼我用@Override獲得「必須重寫超類方法」?
- 27. 爲什麼WEKA-TestSets必須具有類屬性?
- 28. 爲什麼這個alignment屬性必須在typedef中指定?
- 29. 爲什麼視圖屬性必須分配給變量?
- 30. 爲什麼依賴屬性必須是靜態
您還可以添加各種修飾符,如受保護等。 – Tigraine 2008-12-04 13:15:42
是的,還有其他人說的......您需要一種方法來區分字段和屬性。 – 2008-12-04 13:19:50
有點旁註:有隻讀字段的概念。該框架將確保這些只寫入一次。它與私人制片人或獲得者不同,如果你有權限的話可以寫出來。 – 2008-12-04 13:24:38