Mehrdad の回答であなたのコメントを読んだので、私はあなたの問題をもう少しよく理解していると思います。
開発者が作成しているクラスのプライベート状態にアクセスしたり、検証ロジックをバイパスしたりする能力について懸念しているようです。これは、状態をクラスにまったく含めるべきではないことを示唆しています。
次の戦略を提案します。ValidatedValue を表すジェネリック クラスを記述します。このクラスはバッキング値のみを保持し、get および set メソッドを介したアクセス/ミューテーションのみを許可します。検証ロジックを表すデリゲートが ValidatedValue に渡されます。
public class ValidatedValue< T >
{
private T m_val;
public ValidationFn m_validationFn;
public delegate bool ValidationFn( T fn );
public ValidatedValue( ValidationFn validationFn )
{
m_validationFn = validationFn;
}
public T get()
{
return m_val;
}
public void set(T v)
{
if (m_validationFn(v))
{
m_val = v;
}
}
}
もちろん、必要に応じてデリゲートを追加することもできます (たとえば、変更前後の通知をサポートするため)。
クラスは、プロパティのバッキング ストアの代わりに ValidatedValue を使用します。
次の例は、100 未満であることが検証された整数を持つクラス MyClass を示しています。例外をスローするロジックは、ValidatedValue ではなく、MyClass にあることに注意してください。これにより、MyClass に含まれる他の状態に依存する複雑な検証ルールを実行できます。ラムダ表記を使用して検証デリゲートを構築しました。代わりに、メンバー関数にバインドすることもできました。
public partial class MyClass
{
private ValidatedValue<int> m_foo;
public MyClass()
{
m_foo = new ValidatedValue<int>(
v =>
{
if (v >= 100) RaiseError();
return true;
}
);
}
private void RaiseError()
{
// Put your logic here....
throw new NotImplementedException();
}
public int Foo
{
get { return m_foo.get(); }
set { m_foo.set(value); }
}
}
それが役立つことを願っています-元のトピックから多少外れていますが、実際の懸念とより一致していると思います. 私たちが行ったことは、検証ロジックをプロパティから取り除き、それをデータに配置することです。これはまさにあなたが望んでいた場所です。