HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Countable and uncountable sets in .NET (IEnumerable and Predicate)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
predicatenetcountableandsetsuncountableienumerable

Problem

There is a full featured support of countable sets in .NET: IEnumerable. What about uncountable sets; sets defined by predicate? How can they be manipulated and interact with IEnumerable?

UPDATED: Countable and uncountable sets

Was: Condition-class.

Demo (you can play with it here online):

using static System.Console;
using static System.String;
class Program
{
    static void Main(string[] args)
    {
        var NullOrEmpty = new Set(string.IsNullOrEmpty);
        var NullOrWhiteSpace = new Set(string.IsNullOrWhiteSpace);
        var WhiteSpace = NullOrWhiteSpace - NullOrEmpty;

        WriteLine(WhiteSpace * " "); // True

        var LowIncome = new Set(i => i (i => i > 140000);
        var MiddleIncome = !LowIncome && !HighIncome;

        var salaries = new[] { 25000, 40000, 35000, 80000, 65000, 120000, 200000 };            
        WriteLine(Join(",", salaries - MiddleIncome)); // 25000, 200000
    }
}


Where full set of operations is defined as:

```
class Set
{
public Set(Predicate predicate)
{
Predicate = predicate;
}

public static bool operator *(Set left, T right) =>
left.Predicate(right);

public static bool operator *(T left, Set right) =>
right.Predicate(left);

public static Set operator *(Set left, Set right) =>
new Set(i => left.Predicate(i) && right.Predicate(i));

public static IEnumerable operator *(Set left, IEnumerable right) =>
right.Where(i => left.Predicate(i));

public static IEnumerable operator *(IEnumerable left, Set right) =>
left.Where(i => right.Predicate(i));

public static Set operator +(Set left, T right) =>
new Set(i => left.Predicate(i) || right.Equals(i));

public static Set operator +(T left, Set right) =>
new Set(i => left.Equals(i) || right.Predicate(i));

public static Set operator +(Set left, Set right) =>
new Set(i => left.Predicate(i) || right.Predicate(i));

public static Set o

Solution

Interesting try to use C#'s operators for set operations.

However, I think it is not a good extension in productive code because

  • you have to learn the meaning of the operators first (and therefore check the implementation because operators are not descriptive).



  • compared to methods, it is not possible to add comments to the operators



  • the expressions are a little bit confusing to me. For example the '-' operator return different results depending on the position of the operands.



Further more, the functional features of C# provide already similar possibilities. For instance:

var salaries = new[] { 25000, 40000, 35000, 80000, 65000, 120000, 200000 };
var isLowIncome = new Func(i => i (i => i > 140000);
var isMiddleIncome = new Func(i => !isLowIncome(i) && !isHighIncome(i));

Console.WriteLine(string.Join(",", salaries.Where(s => isLowIncome(s)))); // 25000, 200000
// or
Console.WriteLine(string.Join(",", salaries.Where(isLowIncome))); // 25000, 200000


That is readable and understandable for each C# developer without studing a framework.

Code Snippets

var salaries = new[] { 25000, 40000, 35000, 80000, 65000, 120000, 200000 };
var isLowIncome = new Func<int, bool>(i => i < 30000);
var isHighIncome = new Func<int, bool>(i => i > 140000);
var isMiddleIncome = new Func<int, bool>(i => !isLowIncome(i) && !isHighIncome(i));

Console.WriteLine(string.Join(",", salaries.Where(s => isLowIncome(s)))); // 25000, 200000
// or
Console.WriteLine(string.Join(",", salaries.Where(isLowIncome))); // 25000, 200000

Context

StackExchange Code Review Q#131971, answer score: 4

Revisions (0)

No revisions yet.