![](/img/trans.png)
[英]Should I use a private property/field with a public getter method or directly use a public property for proper encapsulation?
[英]Should I use a private field of a public property inside a class where I declare that property?
假設我有一個這樣的課程:
public class A
{
private BaseSettings fieldA;
public ISettings PropertyA
{
get {return fieldA;}
set {fieldA= value as BaseSettings;}
}
}
其中BaseSettings實現ISettings。 在類A內,如果我想訪問BaseSettings的名為PropertyB的屬性,這是一個好習慣:
fieldA.PropertyB;
要么
((BaseSettings)PropertyA).PropertyB;
可能有人說第一種方法可能會將提示隱藏在屬性更改時。 例如,代碼可以偵聽PropertyChangedEvent,然后在不引發事件的情況下更改屬性的值。
另一個人可能會說,第二種方法可能會帶來這樣的風險:當不熟悉當前代碼的人對其進行修改時,他可能會將PropertyA強制轉換為實現ISettings的其他類型。
兩種方法都有其缺點。 在良好的編程習慣中,哪一個更可取?
編輯:根據以下評論添加:
我同意將后備字段設置為ISettings是絕對有意義的。 但是,我應該怎么做才能確保PropertyA始終是BaseSettings的類型。 這將引發一個問題:“那為什么不同時將屬性和后備字段都設置為BaseSettings?”。
屬性及其支持字段不同的原因在於,類A也實現了這樣的接口
public interface IControlWithSettings
{
ISettings OwnerSettings
{
get;
set;
}
ISettings Settings
{
get;
set;
}
}
所以實際的classA看起來像這樣
public class BaseForm: Form, IControlWithSettings
{
private BaseFormSettings settings;
public ISettings Settings
{
get {return settings;}
set {settings= value as BaseFormSettings;}
}
}
我還有另一個B類也可以實現IControlWithSettings
public class BaseUserControl: UserControl, IControlWithSettings
{
private BaseUserControlSettings settings;
public ISettings Settings
{
get {return settings;}
set {settings= value as BaseUserControlSettings ;}
}
}
BaseFormSettings : ISettings
和BaseUserControlSettings : ISettings
。 這是實際的ISettings界面
public interface ISettings
{
Dictionary<string, ISettings> Children { get; set; }
}
我將“ as”強制轉換是設置器中的一個副作用,如果設置設置為錯誤的設置,它將忽略並返回null。 我在某處讀到說我不應該在二傳手中拋出異常。 因此,將其設為null是我告知發生了某些錯誤的方式。
那么什么是更好的方法。 我設計錯了嗎?
如您所述,這兩種方法都有其缺點,並且還取決於屬性設置器是否可能包含某些其他邏輯(例如,驗證),您可以在類內部使用或規避此其他邏輯。
如果沒有什么可以反對的,我將使用直接訪問該字段的方法。 它更加整潔,並且避免了所有此類轉換。
但是通常:為什么在屬性本身具有接口類型的情況下,為什么要使用派生類型來支持屬性? 這沒有多大意義。 為什么不只是:
public class A
{
public ISettings PropertyA { get; set; }
}
這樣會更清潔,甚至您的問題也不會出現。
編輯 (基於答案的編輯)
在“雙重使用”支持字段的情況下,類型轉換是有意義的。 但是我不認為(以前從未聽說過)從屬性設置器中引發異常不是一件壞事。 相反:驗證值並在不通過時拋出異常是非常常見的模式。
因此,在您的具體情況下,我將驗證正確類型的值,如果該值不正確則拋出該異常,並在內部使用后備字段繞過此類型檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.