Up-to-date version: Countable and uncountable sets in .NET (IEnumerable and Predicate).
Here is my own predicate class; it is equipped with some operators. Demo:
using static BusinessObjects;
using static Console;
class Program
{
static void Main(string[] args)
{
WriteLine(Sell("John Doe", "test@example.com", 10000));
WriteLine(Sell("John Doe", "test@example.com", 100000));
WriteLine(Sell("John Doe", "test@example.com", 150000));
}
static string Sell(string name, string email, int income)
{
if (name == NullOrWhiteSpace || email != ValidEmail)
throw new Exception("Bad, bad customer.");
if (income == LowIncome)
return "Sell car.";
var middleIncome = !LowIncome && !HighIncome; // magic!!!
if (income == middleIncome)
return "Sell home.";
return "Sell big.";
}
}
Where business definitions are (verbose, verbose C#):
static class BusinessObjects
{
public static readonly Condition<string> NullOrEmpty =
new Condition<string>(string.IsNullOrEmpty);
public static readonly Condition<string> NullOrWhiteSpace =
new Condition<string>(string.IsNullOrWhiteSpace);
public static readonly Condition<string> ValidEmail =
new Condition<string>(new EmailAddressAttribute().IsValid);
public static readonly Condition<int> LowIncome =
new Condition<int>(i => i < 30000);
public static readonly Condition<int> HighIncome =
new Condition<int>(i => i > 140000);
}
Library class:
public class Condition<T>
{
public Condition(Predicate<T> predicate)
{
Predicate = predicate;
}
Predicate<T> Predicate { get; }
public static bool operator ==(Condition<T> left, T right) =>
left.Equals(right);
public static bool operator ==(T left, Condition<T> right) =>
right.Equals(left);
public static bool operator !=(Condition<T> left, T right) =>
!left.Equals(right);
public static bool operator !=(T left, Condition<T> right) =>
!right.Equals(left);
public static bool operator true(Condition<T> x) => false;
public static bool operator false(Condition<T> x) => false;
public static Condition<T> operator |(Condition<T> left, Condition<T> right) =>
new Condition<T>(v => left.Equals(v) || right.Equals(v));
public static Condition<T> operator &(Condition<T> left, Condition<T> right) =>
new Condition<T>(v => left.Equals(v) && right.Equals(v));
public static Condition<T> operator !(Condition<T> eq) =>
new Condition<T>(v => !eq.Equals(v));
public override bool Equals(object obj) =>
obj is T && Predicate((T)obj);
public override int GetHashCode()
{
throw new NotSupportedException();
}
}
What do you think? Does this business definitions looks readable and easily reusable?
mediumIncome
. \$\endgroup\$