C# でのプロパティの誤った変更を防ぐための明示的インターフェイスの使用
-
19-09-2019 - |
質問
以前は気づかなかった 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 を実装するエンティティをチェックし、エンティティを永続化するときに日付を設定できます。
私の質問は次のとおりです。
- 定義された動作に依存しているのでしょうか、それともすべての C# コンパイラーがこの方法でメソッドを解決することが保証されていますか?C# 標準ではこの種のメソッド解決は未定義であると規定されていることを知り、たとえば Mono 用にビルドするときに誤って恐ろしいスタック オーバーフローが発生することは望ましくありません。
- これを行うためのより良い (理想的には簡潔な) 方法はありますか?ModelBinder に安全なインターフェイスをコントローラーに渡すこともできますが、コードを節約できるとは思えませんし、プロパティの偶発的な変更を最小限に抑える透過的なアプローチが提供されるとも思えません。
解決
これは完全に明確に定義されています。 (GET / SETの体内からも含む)インタフェースを使用する場合、明示的なインタフェースの実装は、優先順位を取り、定期的な性質は、そうでなければ有効になります。
... ...私が提供できる最高のは、それはあまり冗長にするために、それを再フォーマットすることです、それは整然と作るためとして、
DateTime IHaveUpdateDateFields.CreatedOn
{
get { return CreatedOn; }
set { CreatedOn = value; }
}
(this
暗黙冗長であることに注意してくださいも)
余談として - 安全性は便宜上、ない保証は...外部の発信者がまだあなたのインターフェースを使用することができ、通常は(AB)はprotected
のような過去の単なるものをジャンプするためにリフレクションを使用することができます - あるいは単にフィールドを設定直接ます。
所属していません StackOverflow