ASP.NET Hosting

Playing with operator overloading and code generation: enums and sets

In Delphi there is a concept that is not exactly translated in C#: sets. For example you can define sets and work with them like this:

type TSetOfIntegers = set of 1..250;
type Abc = set of (A, B, C);

var Set1, Set2: TSetOfIntegers;
var CharacterSet: set of 'a'..'z';

Set1 := [1, 3, 5, 7, 9];
Set2 := [2, 4, 6, 8, 10];
CharacterSet := ['a','b','c'];

What's nice is that you can use the in keyword to test whether an element is part of the set. You can also do arithmetical operations on sets.

Just as a pretext, I tried to reproduce this behaviour in C#. We don't have templates (oops, generics!) yet, so I went with code generation with CodeSmith. The result is certainly not performant at all, but is an interesting use of operator overloading and code generation.
Note that the result here is merely a simple collection and so very different from Delphi's implementation of the concept!
I added however an implementation that works with flags enums (see the Flags attribute) which allow enumerations to be treated as bit fields. This is closer to what Delphi does and certainly more performant.

Here is an example of what I tried to reproduce:

type TAbc = set of (A, B, C);

procedure TForm1.Button1Click(Sender: TObject);
var abc: TAbc;
begin
  abc := [A, B];
  ShowMessage(BoolToStr(A in abc, true));
  ShowMessage(BoolToStr(C in abc, true));
  abc := abc + [C];
  ShowMessage(BoolToStr(C in abc, true));
  abc := abc + [C];
end;

You can take a look at the source code to see how it works. The interesting parts are:

  • the Set.cst file which is a CodeSmith template file
  • the two XML files which are CodeSmith property files which define specific implementations of the template
  • the Form1.cs file which contains test code

In this sample you'll find code like

  • AbcSet set = new AbcSet(Abc.A) // to create a new set 
  • set & Abc.A or set.Contains(Abc.A) // to test whether a set contains an element
  • set = set + Abc.B or set += Abc.B // to add an element to a set

Note that you'll need CodeSmith to use the templates.
I won't go into the details of the source code, so go check it out by yourself and come back to me with questions if you have some.

1 Comment

  • you are on the right track regarding generics -hopefully with generics we'll have a more elaborate library like the STL. STL has an associative container like Sets.

    Good stuff with your 'Set' implementation..got to try it out..

Comments have been disabled for this content.