Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java enums vs C# enums - missing features

Tags:

java

c#

enums

in java I could easily describe an enum with aditional data.
I could describe it something like this

public enum OperatorType
{
    GreaterOrEqual  (">=", "GreaterOrEqual"),
    Greater         (">" ,"Greater"),
    Less            ("<", "Less"),
    LessOrEqual     ("<=", "LessOrEqual"),
    Equal           ("==", "Equal"),
    Between         ("Between", "Between"),
    Around          ("Around","Around");

    private final String symbol;
    private final String name;

    private OperatorType(final String symbol, final String name) {
        this.symbol = symbol;
        this.name = name;
    }
}

And then add a static method that iterates over values(), adds all data to a hashmap and allow to retrieve from the map full enum data by one of its attriburtes as a key.

In brief, enum is a very developed type in java.

Now,
moving to c#, what are my options?
I want to hold an enum with its attributes, load it to a map, and retreive by key when I need. Do I have anything to assist (like, a singletone for each enum - which is not a good idea).
Thanks.

like image 369
Bick Avatar asked Nov 18 '12 22:11

Bick


2 Answers

I would just create a class with public static readonly instances of each type and ditch enums altogether. You can use them as dictionary keys or do whatever you like. If you still intend to map them to an underlying data type (int) then you can create implicit operators for that too.

public class OperatorType
{
    private static readonly Dictionary<int, OperatorType> OperatorMapping = new Dictionary<int, OperatorType>();

    public static readonly OperatorType GreaterOrEqual  = new OperatorType(0, ">=", "GreaterOrEqual");
    public static readonly OperatorType Greater         = new OperatorType(1, ">", "Greater");



    public readonly String symbol;
    public readonly String name;
    private readonly int underlyingValue;

    private OperatorType(int underlyingValue, string symbol, string name) {
        this.underlyingValue = underlyingValue;
        OperatorMapping[underlyingValue] = this;

        this.symbol = symbol;
        this.name = name;
    }

    public static implicit operator int(OperatorType operatorType)
    {
        return operatorType.underlyingValue;
    }

    public static implicit operator OperatorType(int value)
    {
        return OperatorMapping[value];
    }
}

Sample usage:

Dictionary<OperatorType, string> operators = new Dictionary<OperatorType, string>();

operators.Add(OperatorType.GreaterOrEqual, "Greater or equal");

Console.WriteLine(operators[OperatorType.GreaterOrEqual]); //"Greater or equal"

OperatorType operatorType = 1;

Console.WriteLine(operatorType.name); //"Greater"

If you don't care about an underlying value, don't include it. Also consider whether or not the Dictionary mapping should be threadsafe for your usage. You can also expose a static IEnumerable<OperatorType> (or other collection) to get all operators defined if you want.

EDIT: On second thought, explicit operators are possibly preferable instead of implicit, both to conform with typical .NET best practices and to better match typical enum conversions.

like image 169
Chris Sinclair Avatar answered Oct 09 '22 07:10

Chris Sinclair


The most convinient workaround might be to create an extension method to your enum type, and return the associated symbols.

Something like this:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            tester t = tester.x;
            t.testenums();
            Console.ReadKey();
        }


    }

    public static class ext
    {
        public static void testenums(this tester x)
        {
            Console.WriteLine(x.ToString());
        }
    }

    public enum tester
    {
        x,
        y
    }
}

Of course you can write a more complex extension method, with return value, etc, this is just an example how to do it.

like image 36
Robert Avatar answered Oct 09 '22 08:10

Robert