具有結構類型的字段允許直接訪問其成員,而這種類型的屬性則不能。因此,如果Thing.Boz
是Point
類型的字段,那麼想要修改其值X
值的代碼可以簡單地說是Thing.Boz.X += 5;
;如果Thing.Boz
是可變屬性,則有必要使用var tmp = Thing.Boz; tmp.X += 5; Thing.Boz = tmp;
。用暴露的字段更乾淨地寫東西的能力通常是,但不總是,這是一種祝福。
如果Boz
始終可能是一個字段,直接修改其成員會比將其複製到臨時變量,修改它並將其複製回來更乾淨,更快速,更好。如果Boz
類型直接暴露了其可變域(如結構應),而不是在瑣碎的包裝紙包裹其中,它也將有可能使用之類的東西Interlocked
方法對它們 - 這簡直是不可能的性能。以這種方式使用字段實際上只有一個缺點:如果有必要用屬性替換字段,那麼依賴字段的代碼將會中斷,並且可能很難修復。
簡而言之,我認爲在不關心能夠在不需要重新編譯任何消費者的情況下交換不同版本的代碼的情況下,使用屬性而不是字段的最大效果是防止消費者來自編寫代碼的代碼將利用(並且依賴)具有結構類型的暴露字段的語義。
順便提及,到露出的結構類型的字段的替代方案將是暴露一個ActOnXXX
方法。例如:
delegate void ActionByRef<T1>(ref T1 p1);
delegate void ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2,T3>(ref T1 p1, ref T2 p2, ref T3 p3);
// Method within the type that defines property `Boz`
void ActOnBoz<T1>(ActionByRef<Point, T1> proc, ref T1 p1)
{
proc(ref _Boz, ref p1); // _Boz is the private backing field
}
守則,想增加一些局部變量q
到Thing.Boz.X
可以打電話Thing.ActOnBoz((ref Point pt, ref int x) => {pt.X += x;}, ref q);
,並有行動直接Thing._Boz
執行,即使該字段不被暴露。
中@JasonBunting您的評論感嘆不可變的類型和只讀。我很好奇爲什麼你不能通過 MyProperty {get;私人設置; }? – 2008-10-16 09:43:23
@Robert:因爲我沒有得到免費的驗證,認爲我的實現沒有修改狀態。 – 2008-10-16 15:24:46
如果您不信任自己,請使用後臺字段並編寫單元測試。 私有隻讀字符串名稱; public string Name {get {return name; }} 「屬性或索引」 ......名稱」不能被分配到 - 它是隻讀 – 2008-10-16 20:36:57