Ну, просто, если у вас есть класс 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);
Конечно, это только одно из возможных решений.
Если вы удалите вышеуказанное общее ограничение («где T: Entity»), вы можете сделать это универсальным механизмом правил, который можно использовать с любым POCO. Вам не нужно будет создавать класс для каждого типа использования, который вам нужен. Поэтому, если бы я хотел использовать этот же класс в TextBox, я мог бы использовать следующее (после удаления общего ограничения):
var rule = new ValidationRule<TextBox>(tb => tb.Text.Length > 0);
rule.IsValid(myTextBox);
Это довольно гибкий способ. Совместное использование лямбда-выражений и обобщений очень эффективно. Вместо того, чтобы принимать Func или Action, вы можете принять Expression> или Expression> и иметь прямой доступ к дереву Express, чтобы автоматически исследовать такие вещи, как имя метода или свойства, тип выражения и т. Д. И люди, использующие ваш класс не должен был бы изменить одну строку кода.