Question

Are there any good solutions to represent a parameterized enum in C# 3.0? I am looking for something like OCaml or Haxe has. I can only think of class hierarchy with a simple enum field for easy switching for now, maybe there are better ideas?

See Ocaml example below in one of the replies, a Haxe code follows:

enum Tree {
   Node(left: Tree, right: Tree);
   Leaf(val: Int);
}
Was it helpful?

Solution

Not being familiar with OCaml or Haxe, and not being clever enough to understand the other explanations, I went and looked up the Haxe enum documentation - the 'Enum Type Parameters' bit at the bottom seems to be the relevant part.

My understanding based on that is as follows:

A 'normal' enum is basically a value which is restricted to the things that you have defined in your enum definition. C# Example:

enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;

c can either be Red, Green, Yellow, or Blue, but nothing else.

In Haxe, you can add complex types to enums, Contrived example from their page:

enum Cell<T>{ 
  empty; 
  cons( item : T, next : Cell<T> )
}

Cell<int> c = <I don't know>;

What this appears to mean is that c is restricted to either being the literal value empty (like our old fashioned C# enums), or it can also be a complex type cons(item, next), where item is a T and next is a Cell<T>.

Not having ever used this it looks like it is probably generating some anonymous types (like how the C# compiler does when you do new { Name='Joe'}.
Whenever you 'access' the enum value, you have to declare item and next when you do so, and it looks like they get bound to temporary local variables.

Haxe example - You can see 'next' being used as a temporary local variable to pull data out of the anonymous cons structure:

switch( c ) {
  case empty : 0;
  case cons(item,next): 1 + cell_length(next);
}

To be honest, this blew my mind when I 'clicked' onto what it seemed to be doing. It seems incredibly powerful, and I can see why you'd be looking for a similar feature in C#.

C# enums are pretty much the same as C/++ enums from which they were originally copied. It's basically a nice way of saying #define Red 1 so the compiler can do comparisons and storage with integers instead of strings when you are passing Color objects around.

My stab at doing this in C# would be to use generics and interfaces. Something like this:

public interface ICell<T> {
   T Item{ get; set; }
   ICell<T>{ get; set; }
}

class Cons<T> : ICell<T> {
  public T Item{ get; set; } /* C#3 auto-backed property */
  public Cell<T> Next{ get; set; }
}

class EmptyCell<T> : ICell<T>{
  public T Item{ get{ return default(T); set{ /* do nothing */ }; }
  public ICell<T> Next{ get{ return null }; set{ /* do nothing */; }
}

Then you could have a List<ICell<T>> which would contain items and next cell, and you could insert EmptyCell at the end (or just have the Next reference explicitly set to null). The advantages would be that because EmptyCell contains no member variables, it wouldn't require any storage space (like the empty in Haxe), whereas a Cons cell would.
The compiler may also inline / optimize out the methods in EmptyCell as they do nothing, so there may be a speed increase over just having a Cons with it's member data set to null.

I don't really know. I'd welcome any other possible solutions as I'm not particularly proud of my one :-)

OTHER TIPS

Use a class that with static properties to represent the enumeration values. You can, optionally, use a private constructor to force all references to the class to go through a static property.

Take a look at the System.Drawing.Color class. It uses this approach.

C# (the .NET framework in general, as far as I know) doesn't support parametrized enums like Java does. That being said, you might want to look at Attributes. Some of the features that Java enums are capable of are somewhat doable through Attributes.

What's wrong with just using a class for this? Its ugly, but thats how the Java people did it until they had language integrated Enum support!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top