Did you know that implementing a mechanism similar to discriminated unions in C# or any other language that supports interfaces and lambdas is pretty simple?
By rotating structure members to parameters and passing lambdas instead of data, a protocol transport mechanism similar to discriminated union is born. No more switch / cases to interpret a protocol are required. It’s kind of an old idea, probably related to RPC, and of course functional programming languages.
Instead of moving data around, we move lambdas.
So for example you want to support a change event of a set:
sealed class Set<ItemT>
{
// scary at first, but this is actually what we want, our change
// notification is a lambda that calls a method in ISetChange.
//
public event Action<Action<ISetChange<ItemT>>> OnChanged;
public void add(ItemT item)
{
... add item
//
if (OnChanged != null)
OnChanged(i => i.add(item));
}
public void remove(ItemT item)
{
... remove item from set
//
if (OnChanged != null)
OnChanged(i => i.remove(item));
}
};
Our union is now an interface:
interface ISetChange<ItemT>
{
void add(ItemT item);
void remove(ItemT item);
}
And another class tracking these may look like:
class SetTracker<ItemT> : ISetChange<ItemT>
{
public void add(ItemT item)
{
// item was added
}
public void remove(ItemT item)
{
// item was removed.
}
}
You can now connect:
var setOfInts = new Set<int>();
var tracker = new SetTracker<int>();
setOfInts.OnChanged += a => a(tracker);
Additionally, you may decide to derive Set
Using lambdas to transport changes across your application saves you a lot of time in generating protocol classes. It may, however, come at an increased cost of performance.
yours
armin