簡體   English   中英

封裝C#newbie

[英]Encapsulation C# newbie

C#的新手,我知道封裝只是一種“保護數據”的方式。 但我還不清楚。 我認為,get和set訪問都添加這些方法中的測試,以檢查是否參數滿足一定條件,允許外部函數來獲取和設置任何東西,這樣才:

private string myName;
public string MyName;// this is a property, speical to c#, which sets the backing field.

private string myName = "mary";// the backing field.

public string MyName // this is a property, which sets/gets the backing field.
{
    get
    {
        return myName;
    }
    set
    {
        if (value != "Silly Woman"){ 
           myName = value;
        }

    } 
}

但是我一直在看c#中的代碼看起來像這樣:

public string MyName { get; set; }

為什么你只是在那里得到一個沒有任何東西的get-set, - 這不僅僅是公開你的私人支持領域嗎? 如果您可以從外部獲取並設置它,為什么不直接進行?

實際上,創建一個自動屬性如下:

public string Name { get; set; }

與構建由字段支持的屬性相同:

private string _name;
public string Name {
    get { return _name; }
    set { _name = value; }
}

這些屬性的重點不是隱藏數據。 正如你所觀察到的,他們不會這樣做。 相反,這些屬性可以執行其他操作,而不僅僅是使用字段:

public string Name {
    get { return _name; }
    set { if (value == null) throw new Exception("GTFO!"); _name = value; }
}

另一件事是,你可以使屬性虛擬

public virtual string Name { get; set; }

如果被覆蓋,則可以在派生類中提供不同的結果和行為。

通過使用public string MyName { get; set; } public string MyName { get; set; } public string MyName { get; set; } ,你離開以后更改它的邏輯,而無需重新編譯/改變使用你的財產的其他代碼的能力。

例如,如果您正在創建一個庫並且v1使用一個字段而v2使用一個屬性,那么使用v1的應用程序將無法在不重新編譯的情況下使用v2(如果它們是用某種.NET語言編寫的,則可能會更改代碼訪問字段的不同語法)。

另一個重要的區別在於序列化場景 - 其中很多都不支持字段。 此外,任何需要屬性的接口都不能在不使用屬性的情況下實現,但根據接口,可能不需要在其中執行任何其他檢查/邏輯。

如果您想稍后添加檢查/測試,則更容易更改代碼。 特別是如果您的代碼中有許多繼承和許多類,則很難將實現從公共變量更改為公共屬性。

此外,您可以在屬性中添加get和set不同的屬性,例如,如果您正在使用反射。 屬性的get和set是內部不同的方法。 如果您只有一個公共變量/字段,則無法為不同的訪問方式添加不同的屬性。

是的,但您可以輕松地將其更改為:

public string MyName { get; private set; }

另外,屬性在其他場景中使用,比如DataContract和Serialization ......所以,這是一個很好的功能...(大多數,語法糖。我認為)編輯:我把它拿回來...你可以應用虛擬它,所以它不一樣

它使以后更容易添加邏輯。 如果您的類具有要更改為屬性的公共字段,則必須重新編譯使用該類的所有內容。 這是我最初不理解的關鍵點。

如果你有一個班級:

public class MyClass
{
    public string MyString;
}

您可以像這樣訪問值:

var myClass = new MyClass();
string s = myClass.MyString;

現在將其更改為屬性:

public class MyClass
{
    public string MyString { get; set; }
}

怎么訪問? 完全相同的方式:

var myClass = new MyClass();
string s = myClass.MyString;

沒什么大不了的,對吧? 實際上....

實際上,屬性被編譯為getter和setter方法:

get_MyString()set_MyString(string value)

所以這兩種方法確實產生了不同的編譯代碼。 現在,如果您使用此類的所有代碼都在同一個項目中,那么這並不是一件大事,因為它將全部編譯在一起。 但是,如果您有一個已經分發的API庫,那么更新它可能會更大。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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