Usually, if we want to do any validations, we will use if and else conditions. Then return false if any one of the business rule is failed. Typical example for customer information object validation
public bool IsValid(CustomerInfo customerInfo)
{
if (String.IsNullOrEmpty(customerInfo.FirstName))
{
return false;
}
else if (String.IsNullOrEmpty(customerInfo.LastName))
{
return false;
}
else if (customerInfo.Age == 0)
{
return false;
}
return true;
}
If you know how the Func<T>
delegate works, then we can do the same validation using Lambda expression very easy and with less number of code.
Look at the below code which does the same validation, but using Lambda expressions.
One good thing about this pattern is, it allow us to follow "Open Close Principle".
public bool IsValidByLamda(CustomerInfo customerInfo)
{
List<Func<CustomerInfo, bool>> rules = new List<Func<CustomerInfo, bool>>
{
x => String.IsNullOrEmpty(x.FirstName),
x => String.IsNullOrEmpty(x.LastName),
x => x.Age == 0
};
return rules.All(x => x(customerInfo) == false);
}
Here, instead of writing if and else conditions, we are defining rules. each rule is the delegate which accept the CustomerInfo parameter and validate the respective field. So, we have collection of rules that should be satisfied for the validation to be true.
Finally, we call "All" operator of Linq generics that runs through the each and every rule we defined in the "rules" collection by passing "customerInfo" object. If any one of the rule returned true, then "All" operator return false. Because have written a condition to make sure that all rules are returning false.
"All" operator - Determines whether all elements of a sequence satisfy a condition.