2009-11-11 17 views
2

我偶然發現了之前沒有注意到的C#方法解析功能。也就是說,當我明確實現一個支持setter的接口時,隱式接口只提供一個受保護的集合,編譯器在我調用它時明智地遵循受保護的集合。所以我獲得了自動實現屬性的大部分便利,但是我可以防止不應該更改它們的客戶對字段的意外修改。使用顯式接口來防止意外修改C#中的屬性

舉個例子,

virtual public DateTime CreatedOn { get; protected set; } 
virtual public DateTime? ModifiedOn { get; protected set; } 
#region IHaveUpdateDateFields Members 

DateTime IHaveUpdateDateFields.CreatedOn 
{ 
    get 
    { 
     return this.CreatedOn; 
    } 
    set 
    { 
     this.CreatedOn = value; 
    } 
} 

DateTime? IHaveUpdateDateFields.ModifiedOn 
{ 
    get 
    { 
     return this.ModifiedOn; 
    } 
    set 
    { 
     this.ModifiedOn = value; 
    } 
} 

然後我的模型綁定代碼不小心設置日期,但我的ORM事件偵聽器可以檢查實現IHaveUpdateDateFields和堅持我的實體時設定日期的實體。

我的問題是:

  1. 上午我依靠定義的行爲,還是我保證所有的C#編譯器將解決方法,這種方式?例如,我不希望發現C#標準說這種方法解析是未定義的,然後在我爲Mono構建時意外地發生了可怕的堆棧溢出。
  2. 有沒有更好的(理想比較爽)的方式來做到這一點?我可以將一個ModelBinder安全的接口傳遞給我的控制器,但這看起來似乎不會節省我的代碼,我認爲它不會提供透明的最小化意外修改屬性的方法。

回答

3

這是完全明確的;在使用接口時顯式接口實現優先,否則常規屬性會生效(包括從get/set的內部)。

至於使之更爲簡潔...我可以提供最好是重新格式化它,使之更簡潔...

DateTime IHaveUpdateDateFields.CreatedOn 
{ 
    get { return CreatedOn; } 
    set { CreatedOn = value; } 
} 

(還要注意的是,this是隱式冗餘)

順便說一句 - 安全只是一種方便,不是保證......外部呼叫者仍然可以使用您的界面,並且通常可以使用反射來跳過像protected這樣的單純的事物 - 甚至可以直接設置字段。

+0

是的,這是我的目標......與大多數面向對象的構造一樣,我試圖防範錯誤,而不是欺詐。受保護的set idiom用於我們系統中的ID,當然NHibernate使用反射工作。 – JasonTrue 2009-11-11 19:56:27