Is this Java Enumeration being used / designed correctly?
I was tasked with converting some Java code to C # and came across the following enum (I had to generalize it because the code is proprietary, sorry). The general purpose of the code is to convert from "non-base unit" to "base unit" (for example, converting from, say, kilometers to millimeters or whatever, they have a ton of conversions). The only thing I changed were the variable names. The template is exactly the same as 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
}
}
Then it is called in code like this:
public static void main( String[] args )
{
ThisIsAnEnum.typeKilom.convertSomething(aDouble, bDouble);
}
I have a couple of questions:
- Is this use of enums good practice in Java?
- If yes or no, what approach should be taken in C #? Can you do something like this? Even if I can, I'm not sure if this approach is correct.
I am not asking someone to convert this for me ... is it just a good approach and (if it is) should I try to do the same in C #. If not, what approach should be taken?
Using java enums is a subjective question that I am not qualified to answer. I can say that you could solve your problem in C # using an extension method. 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
}
}
Is this use of enums good practice in Java?
Quite right. This is exactly the kind of use that was provided for enums that were introduced in Java.
which approach should I use in C #?
Since C # enum
doesn't have the same capability, you'll need to model it in some other way. One approach would be to define a class or interface using methods from your Java enum
and create a bunch of instances public readonly
to mimic the entries enum
:
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;
}
}
}
Usage Func<double,double,double>
allows one class to be used for several different logical purposes while still maintaining instance-based dispatch.
One of the unfortunate consequences of this approach is that you cannot switch
on these enum
s.