[英]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.