簡體   English   中英

C# 中的自動屬性是什么?它們的用途是什么?

[英]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 還提醒我:

如果您問為什么要使用屬性或自動屬性,這就是其背后的設計理念。

一項重要的設計原則是永遠不要將字段公開為公共字段,而是始終通過屬性訪問所有內容。 這是因為你永遠無法判斷一個字段何時被訪問,更重要的是它何時被設置。 現在,很多時候,在設置或獲取值時不需要任何處理(例如,范圍檢查)。 這就是創建自動屬性的原因。 它們是創建屬性的一種簡單的單行方式。 它的后備存儲是由編譯器創建的。

雖然這就是我什至為我的內部程序所做的,但對於為公共使用而設計的程序(用於銷售、開源等)來說,這可能更為重要。 如果您使用自動屬性,然后決定需要在setget執行其他操作,則可以輕松更改代碼而不會破壞公共接口。

更新

作為對下面評論的澄清點,如果所有代碼都是您自己的,那么不,它可能對您來說屬性和字段之間沒有太大區別。 但是,如果您正在設計一個將被其他人使用的庫,那么除非首先重新編譯使用該庫的代碼,否則在公共字段和屬性之間來回切換將導致異常。

作為測試,我創建了一個庫項目並聲明了一個名為TestData的屬性。 我創建了一個全新的項目只是為了使用這個庫。 一切都按預期工作。 然后我將該屬性更改為公共字段(名稱保持不變)並復​​制到新庫 DLL 上,而無需重新編譯使用項目。 結果是拋出異常,因為代碼期望找到方法屬性方法get_TestDataset_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

希望這可以幫助。

除了前面答案中提到的方面,我還會注意到自動屬性和字段之間的一些差異,因為它們看起來非常相似並且它們的用法幾乎相同:

  • 可以在需要時輕松開發為“經典”屬性,而不會破壞與屬性調用者的任何合同
  • 在 Visual Studio 中開發時允許在 get/set 上設置斷點。 當通過反射完成更改並且更改源不明顯時,這尤其有用

對於任何 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM