簡単に言えば、Entity クラスがあり、その Entity でラムダ式を使用して、何かが有効かどうかを判断する (ブール値を返す) 場合は、Func を使用できます。
したがって、エンティティが与えられた場合:
class Entity
{
public string MyProperty { get; set; }
}
次のように ValidationRule クラスを定義できます。
class ValidationRule<T> where T : Entity
{
private Func<T, bool> _rule;
public ValidationRule(Func<T, bool> rule)
{
_rule = rule;
}
public bool IsValid(T entity)
{
return _rule(entity);
}
}
次に、次のように使用できます。
var myEntity = new Entity() { MyProperty = "Hello World" };
var rule = new ValidationRule<Entity>(entity => entity.MyProperty == "Hello World");
var valid = rule.IsValid(myEntity);
もちろん、それは可能な解決策の 1 つにすぎません。
上記の一般的な制約 (「where T : Entity」) を削除すると、これを任意の POCO で使用できる一般的なルール エンジンにすることができます。必要なすべてのタイプの使用法に対してクラスを派生させる必要はありません。したがって、この同じクラスを TextBox で使用したい場合は、次を使用できます (一般的な制約を削除した後)。
var rule = new ValidationRule<TextBox>(tb => tb.Text.Length > 0);
rule.IsValid(myTextBox);
このようにかなり柔軟です。ラムダ式とジェネリックを一緒に使用すると、非常に強力です。Func または Action を受け入れる代わりに、Expression> または Expression> を受け入れ、Express ツリーに直接アクセスして、メソッドまたはプロパティの名前、式のタイプなどを自動的に調査することができます。クラスはコードを 1 行も変更する必要はありません。