[英]What are Automatic Properties in C# and what is their purpose?
有人可以對 C# 中的自動屬性、它們的目的以及一些示例提供一個非常簡單的解釋嗎? 請盡量用外行的話說!
當屬性訪問器中不需要額外的邏輯時,使用自動屬性。
聲明看起來像這樣:
public int SomeProperty { get; set; }
它們只是語法糖,因此您無需編寫以下更冗長的代碼:
private int _someField;
public int SomeProperty
{
get { return _someField;}
set { _someField = value;}
}
編輯:擴展一點,這些用於使類中的私有變量更容易,但允許它們在類外部可見(不能修改它們)
哦,自動屬性的另一個優點是您可以在接口中使用它們! (不允許任何類型的成員變量)
使用普通屬性,您可以執行以下操作:
private string example;
public string Example
{
get { return example; }
set { example = value; }
}
自動屬性允許你創建一些非常簡潔的東西:
public string Example { get; set; }
因此,如果您想創建一個只能在類中設置的字段,您可以執行以下操作:
public string Example { get; private set; }
這相當於:
private string example;
public string Example
{
get { return example; }
private set { example = value; }
}
或者在 Java 中:
private String example;
public String getExample() {
return example;
}
private void setExample(String value) {
example = value;
}
編輯:@Paya 還提醒我:
如果您問為什么要使用屬性或自動屬性,這就是其背后的設計理念。
一項重要的設計原則是永遠不要將字段公開為公共字段,而是始終通過屬性訪問所有內容。 這是因為你永遠無法判斷一個字段何時被訪問,更重要的是它何時被設置。 現在,很多時候,在設置或獲取值時不需要任何處理(例如,范圍檢查)。 這就是創建自動屬性的原因。 它們是創建屬性的一種簡單的單行方式。 它的后備存儲是由編譯器創建的。
雖然這就是我什至為我的內部程序所做的,但對於為公共使用而設計的程序(用於銷售、開源等)來說,這可能更為重要。 如果您使用自動屬性,然后決定需要在set
或get
執行其他操作,則可以輕松更改代碼而不會破壞公共接口。
更新
作為對下面評論的澄清點,如果所有代碼都是您自己的,那么不,它可能對您來說屬性和字段之間沒有太大區別。 但是,如果您正在設計一個將被其他人使用的庫,那么除非首先重新編譯使用該庫的代碼,否則在公共字段和屬性之間來回切換將導致異常。
作為測試,我創建了一個庫項目並聲明了一個名為TestData
的屬性。 我創建了一個全新的項目只是為了使用這個庫。 一切都按預期工作。 然后我將該屬性更改為公共字段(名稱保持不變)並復制到新庫 DLL 上,而無需重新編譯使用項目。 結果是拋出異常,因為代碼期望找到方法屬性方法get_TestData
和set_TestData
,但不通過方法訪問字段。
Unhandled Exception: System.MissingMethodException: Method not found: 'Void TestLibrary.TesterClass.set_TestData(System.String)'.
at TestLibraryConsumer.Program.Main(String[] args)
許多人已經說過 auto 屬性是語法糖 - 一種編寫簡單屬性的速記方式。 我將處理公共變量和公共屬性之間的差異,以及為什么在兩者之間切換時需要重新編譯。 采取以下措施:
public class MyClass
{
public int MyPublicVariable = 0;
public int MyPublicProperty
{
get;
set;
}
}
一旦編譯,從概念上講,它實際上最終類似於以下內容:
public class MyClass
{
public int MyPublicVariable = 0;
private int MyPublicProperty = 0;
public int get_MyPublicProperty()
{
return MyPublicProperty;
}
public void set_MyPublicProperty( int value )
{
MyPublicProperty = value;
}
}
很久以前,屬性被發明為一種快速簡便的定義 get 和 set 方法對的方法。 它使代碼更具可讀性和更容易理解,因為它們傳達了意圖並確保了一致性。
MyClass myClass = new MyClass();
myClass.MyPublicVariable = 2;
myClass.MyPublicProperty = 2;
再次在概念上編譯后,它最終類似於以下內容:
MyClass myClass = new MyClass();
myClass.MyPublicVariable = 2;
myClass.set_MyPublicProperty( 2 );
因此,更喜歡公共屬性而不是公共變量的原因之一是,如果您需要隨着代碼的發展使用不同的邏輯,那么您的代碼的使用者不一定需要重新編譯。 這就是為什么它通常被認為是最佳實踐的原因。 這也是發明自動屬性的原因 - 在保持這種最佳實踐的同時加快代碼編寫速度。
也有一些關於接口的評論。 接口本質上是一種契約,它保證在實現它們的任何類中存在某些方法。 正如我們從上面知道的,屬性代表一兩個方法,因此它們在接口中工作得很好。
希望這有所幫助。
這是另一個可能感興趣的示例:
public class MyClass
{
private int[] _myArray = new int[ 5 ];
public int MyArray[ int index ]
{
get
{
return _myArray[ index ];
}
set
{
_myArray[ index ] = value;
}
}
}
public class MyClass
{
private int[] _myArray = new int[ 5 ];
public int get_MyArray( int index )
{
return _myArray[ index ];
}
public void set_MyArray( int index, int value )
{
_myArray[ index ] = value;
}
}
請注意:我無法完全記住反編譯屬性時使用的方法簽名。 我認為它是“get_XXX”和“set_XXX”,但它可能是其他非常相似的東西。 只要理解在那里,它可能並沒有太大關系。 最后,無論如何它們都變成了內存地址:-)
它們只是一種編碼快捷方式,可以節省程序員的幾次按鍵操作。 而不是輸入所有這些:
private string _lastName;
public string LastName {
get {
return _lastName;
}
set {
_lastName = value;
}
}
你可以輸入:
public string LastName {
get; set;
}
並讓編譯器自動生成其余部分。
簡化接受的答案,您還可以使用:
public int SomeProperty { get; private set; }
它具有相同的效果,您不再需要為此創建另一個變量。
來自自動實現的屬性(C# 編程指南) :
在 C# 3.0 及更高版本中,當屬性訪問器中不需要額外的邏輯時,自動實現的屬性使屬性聲明更加簡潔。 它們還使客戶端代碼能夠創建對象。
當您聲明一個屬性時,編譯器會創建一個私有的匿名支持字段,該字段只能通過該屬性的 get 和 set 訪問器進行訪問。
class Person
{
public string Name { get; set; }
}
在 C# 的早期版本中,為了使用屬性,您需要創建一個字段來保存值(稱為后備存儲):
private string _something;
public string Prop { get { return _something; } }
從 C# 3.0 開始,不再需要此要求,編譯器會自動為您創建后備存儲,因此無需聲明 _something 字段。
您可以在此處閱讀有關此問題的更多信息: http : //msdn.microsoft.com/en-us/library/bb384054.aspx
希望這可以幫助。
除了前面答案中提到的方面,我還會注意到自動屬性和字段之間的一些差異,因為它們看起來非常相似並且它們的用法幾乎相同:
對於任何 VB.NET 閱讀器,實現方式略有不同。 例如:
''' <summary>The property is declared and can be initialized.</summary>
Public Property MyProperty As String = "SomeValue"
但是,關聯字段可通過添加下划線前綴來顯式使用:
Dim sConcat As String = _MyProperty + _MyProperty
_MyProperty = sConcat
在外部代碼中:
Dim sMyValue As String = oMyClassObj.MyProperty ' = "SomeValueSomeValue"
就我個人而言,我更喜歡這種方法,因為當您處理內部字段或可能暴露的屬性時,您可以在使用代碼中清楚地看到。
使用以下代碼:
using System;
class My Class
{
public string Dummy { get; set; }
public My Class()
{
Dummy = "I'm dummy property";
}
}
class Program
{
static void Main()
{
var my Class = new My Class();
Console .Write Line (my Class .Dummy);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.