[英]Why create private fields for properties?
我一直在研究與字段相比的屬性示例,而我總是不加解釋地看到的一件事是創建一個私有字段,然后創建一個屬性。 為什么我們需要_foo
,而不能只運行類似於下面的代碼,或者用Foo = value
代替Foo = Foo
?
我在運行它時看到它創建了一個堆棧溢出異常,所以我猜想它正在尋找一個值來填充Foo
或value
,但是我認為當我執行def.Foo = 55
時可以處理該def.Foo = 55
。
即使創建私有字段是最佳實踐,我仍然想更好地了解導致溢出的實際原因。
class ABC
{
private int _foo; //Why create this?
public int Foo
{
get { return Foo; }
set
{
Foo = Foo;//more logic would go here. }
}
}
}
class Program
{
static void Main(string[] args)
{
ABC def = new ABC();
def.Foo = 55;
Console.WriteLine($"The value of Foo is {def.Foo}.");
Console.ReadLine();
}
}
這是因為字段和屬性不相同。
private int _foo; //field
public int Foo //property
{
get { return _foo; } //should be _foo
set
{
_foo = value;
}
}
通常,您使用公共屬性來訪問私有字段,因為除了分配/獲取字段的值之外,您可能還想做其他事情。
例:
private bool selectedIndexChanged; //note this additional field
public bool SelectedIndexChanged {
get { return selectedIndexChanged; }
set { selectedIndexChanged = value; }
}
private int selectedIndex; //Why create this?
public int SelectedIndex
{
get { return selectedIndex; }
set
{
selectedIndexChanged = value != selectedIndex; //you update selectedIndexChanged here!
selectedIndex = value;
}
}
請注意,您沒有直接訪問私有字段,而是通過公共屬性訪問它們。 具有屬性的好處是,您不僅可以讀取/分配字段值,還可以執行其他操作 :檢查輸入的有效性,分配其他字段,調用事件等。
即使創建私有字段是最佳實踐,我仍然想更好地了解導致溢出的實際原因。
溢出不是由最佳實踐引起的,而是由錯誤的實踐引起的:
private int _foo; //Why create this?
public int Foo
{
get { return Foo; } //this should not happen, wrong practice
set
{
Foo = Foo; //neither should this happen, another wrong practice
}
}
上面的代碼中發生的是:
同樣:
從而導致溢出...
為什么我們需要_foo,而不能僅僅運行類似於我下面的代碼,或者替換掉?
因為屬性是設置或獲取字段值的方法。 因此,您必須先定義一個字段。 如果您必須暗示內部特別是設置程序中的任何邏輯,則這是必需的。 否則,更常見的是使用自動實現的屬性。
即使在使用自動實現的屬性的情況下,編譯器也會為我們生成一個后備字段。
public Person
{
public string FirstName { get; set; }
}
例如,這樣做
var person = new Person { FirstName = "Bob" };
您創建一個新的Person
對象,其屬性名為FirstName
,其類型為string。 此外,您將人員的FirstName
為Bob。 這是您必須注意的一點。 編譯器將生成一個字符串類型的后備字段,並且在運行時將在此處存儲對人的名字的引用。
上面的類的定義類似於以下定義:
public Person
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
}
實際上,這就是定義自動實現的屬性時,后台編譯器的作用。 基於此,我們可以說對字符串“ Bob”的引用將存儲到_firstName
。
屬性實際上是實際變量的獲取/設置方法。 但是,您並不總是需要擁有私有變量才能擁有屬性。
你可以簡單地擁有
public int Foo { get; set; }
編譯器將為您創建和設置變量。 但是,如果需要限制屬性以免分配錯誤的值或執行一些其他任務,則需要屬性變量。
例:
private int _score;
public int Score
{
get { return _score; }
set
{
if(value > 100)
throw new Exception("Score cannot be more than 100");
_score = value;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.