[英]Correct use of C# properties
private List<Date> _dates;
public List<Date> Dates
{
get { return _dates; }
set { _dates = value; }
}
要么
public List<Date> Dates
{
get;
set;
}
我一直使用前者,這是不正確還是不好的做法? 我從沒想到我可以使用第二種選擇。 我喜歡讓我的封裝變量以下划線開頭,因此可以將它們與方法參數區分開。 我一直都是那樣做的。
使用第一個選項是否有可能導致實例化一個額外的List<Date>
對象,然后將整個_dates
替換為value
,或者比這更聰明?
另外,哪個行業最突出或完全主觀?
如果您需要在getter / setter方法中添加某種邏輯,請使用前者。
否則使用后者。 它使事情變得更加清潔。 您還可以使用自動屬性來實現只讀屬性:
public List<Date> Dates { get; private set; }
或者,如果您不希望人們通過該屬性將任何項目添加到列表中,則可以采用前一種語法:
private List<Date> _dates = new List<Date>();
private ReadOnlyCollection<Date> _readOnlyDates =
new ReadOnlyCollection<Date>(_dates);
public ReadOnlyCollection<Date> Dates
{
get { return _readOnlyDates; }
}
由於.NET如何編譯自動屬性,因此兩者基本上是相同的。 .NET 3.5提供了自動屬性。
它們在內部編譯形式中是等效的,除了您不能以第二種形式訪問編譯器生成的私有變量。
從代碼效率的角度來看,它們也是等效的,即時編譯器通常直接訪問私有變量,而沒有調用訪問函數的開銷(在運行時環境檢查了可訪問性之后)。
從編碼的角度來看,我更喜歡第二個版本,它更緊湊(更少的編寫,更少的閱讀)。
第二種語法在C#3.0中引入。 因此,第一種變體將與舊編譯器更兼容。
我傾向於更多地使用自動屬性,因為屬性是表達您的對象正在執行的操作的一種好方法,但仍然具有一定的保護作用。
我幾乎所有的屬性聲明如下:
public bool IsBlah { get; private set; }
這使其成為一個不錯的,可讀的和受保護的吸氣劑。
但是有時您需要顯式的后備字段:
private bool? _isBlah;
public bool IsBlah
{
get
{
if (_isBlah == null)
{
// Do something expensive here and set _isBlah
_isBlah = true;
}
return _isBlah;
}
}
前者是原始方法,后者是較新的“自動屬性”功能的示例,編譯器通過該功能自動為您生成一個后備字段。
有些人(包括我自己)回避自動屬性,因為語法很容易被誤認為抽象屬性,沒有用於“只讀”屬性的功能,並且帶有私有設置器的自動屬性的語法很笨拙:
public List Dates
{
get;
private set;
}
我還發現讓類的內部實現通過類API訪問字段很不舒服。
第二種變化稱為自動實現的屬性 ,是C#3.0中引入的(因此您以前可能沒有遇到過這種情況)。
如果要創建具有后備字段的簡單屬性並且不需要在“ getter”和“ setter”中實現任何邏輯,則最好使用此格式。 它不僅更加簡潔,而且還迫使您直接訪問該屬性,而不是通過通常是最佳實踐的背景進行訪問。
注意,您仍然可以初始化屬性,只需通過構造函數即可。
public class MyClass
{
public List<Date> Dates
{
get;
set;
}
public MyClass()
{
Dates = new List<Date>();
}
}
我個人更喜歡第一種方法,因為它允許您在返回之前執行一些操作。
EG(一個非常糟糕的例子)
private int _limit;
private int _onHand;
private bool returnToVendor;
public Item(int limit, int onHand)
{
_limit = limit;
_onHand = onHand;
}
public int ReturnStock
{
get
{
if(_onHand > _limit)
{
returnToVendor = true;
return _onHand;
}
}
set
{
_onHand = value;
if(_onHand < _limit)
{
returnToVendor = false;
}
}
}
沒關系 第二個就是糖。 我總是使用第二個,因為它更干凈,但是我偶爾需要訪問支持值。
只要您不必確保在getter中初始化List<Date>
就可以使用這兩個版本。 我只是建議您使用一個版本,並且不要在代碼中混用它。
如果需要初始化,則必須使用第一個版本...
private List<Date> _dates;
public List<Date> Dates
{
get { if (_dates == null) _dates = new List<Date>(); return _dates; }
set { _dates = value; }
}
我相信它們可以編譯為相同的代碼。 后者只是表示前者的語法糖。 我傾向於將后者視為將來邏輯的占位符,可能需要將其放置在屬性中,此時,我將把受影響的屬性轉換為前者。
兩者的編譯方式大致相同(我不知道背景字段的名稱將完全相同,但在功能上是等同的)。
IIRC在.NET 3.0或3.5中添加了執行自動屬性( public List<Date> Dates {get; set;}
)的功能。
據我所記得,我一直在對象內部管理列表屬性,使它們成為只讀。
private IList<DateTime> _dates;
public MyClass() {
_dates = new List<DateTime>();
}
public IList<DateTime> Dates {
get {
return _dates;
}
}
這樣,我確保我訪問列表時永遠不會為空,因為客戶端無法分配它。
但是,對於您的示例,僅在獲取或設置屬性時需要某種邏輯時才需要使用前一種方法。 否則,自動屬性的作用與您完全相同,只是獲取並設置一個私有字段的值。 此外, { get; set; }
{ get; set; }
{ get; set; }
以我的謙卑觀點,可以提高可讀性並幫助其他程序員理解您的意圖。
例如:
public class MyClass {
private IList<DateTime> _dates;
public IList<DateTime> Dates {
get {
return _dates;
} set {
_dates = value;
}
}
}
與
public class MyClasse {
public IList<DateTime> Dates { get; set; }
}
第二種方法至少對我而言使意圖更精簡和快捷。 當不需要在getter和setter內部使用邏輯時,編寫類的代碼將變得更快。
否則,一個不比另一個更好,並且做得完全一樣,說到獲取和設置該屬性的值而沒有邏輯。
最重要的是,您需要熟悉您的代碼。 如果最終結果是您沒有獲得任何改進,並且您喜歡自己在做什么,那么就不僅僅要做。 =)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.