Is this Java Enumeration Used/Designed Correctly?

135 views Asked by At

I was tasked with converting some Java code to C# and came across the following enumeration (I had to generalize it, because the code is proprietary, sorry). The general purpose of the code is to convert from a "non-base unit" to a "base unit" (like converting from say kilometers to millimeters, or whatever. They have a ton of conversions). The only things I changed were the variable names. The pattern is exactly like this in the code...

public enum ThisIsAnEnum implements someInterface
{        
    typeKilom( MetricType.kilometer ),

    typeMillm( MetricType.millimeter );

    public double convertSomething(double dbl1, double dbl2)
    {
        // do stuff
        return a double
    }
}

This is then called in the code as follows:

public static void main( String[] args )
{
    ThisIsAnEnum.typeKilom.convertSomething(aDouble, bDouble);
}

I have a couple questions:

  • Is this use of enumerations a good practice in Java?
  • If yes or if no, what approach should I take in C#? Can you do something similar? Even if I can, I'm not sure that this approach is correct.

I'm not asking for someone to convert this for me... just whether this is a good approach and (if so) should I try to do the same thing in C#. If it's not, then what approach should be taken?

2

There are 2 answers

4
recursive On BEST ANSWER

The use of java enums is a subjective question that I'm not well qualified to answer. I can say that you could solve your problem in C# using an extension method though. I'm not sure what relevance the interface has, but given what you've shown, you can reproduce it like this.

void Main() {
    ThisIsAnEnum.typeKilom.ConvertSomething(1, 2);
}

public enum ThisIsAnEnum {
    typeKilom,
    typeMillm,
}

public static class ThisIsAnEnumExtensions {
    // extension method
    public static double ConvertSomething(this ThisIsAnEnum @this, double dbl1, double dbl2) {
        return dbl1 + dbl2; // do stuff
    }
}
1
Sergey Kalinichenko On

Is this use of enumerations a good practice in Java?

Absolutely. This is exactly the sort of usage that has been envisioned when enumerations where introduced in Java.

what approach should I take in C#?

Since C# enums do not have the same capability, you would need to model it in some other way. One approach would be defining a class or an interface with the methods from your Java enum, and make a bunch of public readonly instances mimicking the enum entries:

public ISomeInterface {
    Func<double,double,double> ConvertSomething {get;}
}

public class ThisIsAnEnum : ISomeInterface {

    public Func<double,double,double> ConvertSomething {get;private set;}

    public MetricType MetricType {get;private set;}

    // Private constructor prevents outside instantiations
    private ThisIsAnEnum(MetricType mt) {
        MetricType = mt;
    }

    public static readonly ThisIsAnEnum TypeKilom = new ThisIsAnEnum(MetricType.Kilometer) {
        ConvertSomething = (dbl1, dbl2) => {
            ...
            return res;
        }
    }

    public static readonly ThisIsAnEnum TypeMillim = new ThisIsAnEnum(MetricType.Millimeter) {
        ConvertSomething = (dbl1, dbl2) => {
            ...
            return res;
        }
    }

}

Using Func<double,double,double> lets you use a single class with multiple different pieces of logic, while preserving the dispatch based on the instance.

One unfortunate consequence of taking this approach is that you wouldn't be able to switch on these enums.