2

以前は気付かなかった 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 セーフ インターフェイスを使用することもできますが、それによってコードが節約されるとは思えず、プロパティの偶発的な変更を最小限に抑えるための透過的なアプローチが提供されるとは思えません。
4

1 に答える 1

3

それは完全に明確に定義されています。インターフェイスを使用する場合は明示的なインターフェイスの実装が優先され、それ以外の場合 (get/set の本体内からのものを含む) は通常のプロパティが有効になります。

整理整頓に関しては...私が提供できる最善の方法は、冗長性を減らすために再フォーマットすることです...

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

this(は暗黙的で冗長であることにも注意してください)

余談ですが、安全性は単なる便利さであり、保証ではありませんprotected.

于 2009-11-11T19:46:55.750 に答える