13

I have generic method that accepts "T" type and this is enumerator. Inside the method I have to call helper class methods and method name depands on type of enumerator.

public Meth<T> (T type) { if (typeof(T) == typeof(FirstEnumType)) { FirstEnumType t = ??? // I somehow need to convert T type to FirstEnumType this.helperFirstCalcBll(t); } else { SecondEnumType t = ??? // I somehow need to convert T type to SecondEnumType this.helperSecondCalcBll(t); } } 
3
  • 1
    Why don't you just cast it? Commented Jul 16, 2015 at 6:52
  • 2
    public Meth, not even once. Commented Jul 16, 2015 at 7:10
  • Why do you have a generic method when you don't actually want to write generic code? If you already know the correct enum type at compile-time, why do you throw it away for runtime dispatch? Why not just call an overloaded method with the specific enum type? Commented Jul 16, 2015 at 7:13

4 Answers 4

17

There is no valid cast from an arbitrary type to an enum type so this is not allowed. You need to cast to object first:

FirstEnumType t = (FirstEnumType)(object)type; 

This "tricks" the compiler by upcasting to object (which is always valid) then down-casts to the enum type. Assuming you have done a runtime type check, the downcast will never fail. However implementing this in the else branch, as given, isn't guaranteed to work.

One would question why the method is even generic in the first place but that is how you can make this particular method work.

Sign up to request clarification or add additional context in comments.

4 Comments

Better to go through int instead of object IMO.
@atlaste That would also not be a valid cast.
Oh wait, right. I always forget generics aren't templates :-)
It's too bad something like this isn't valid in C# despite being perfectly feasible for the CLR: public void Meth<T>() where T:enum.
5
public void Meth(FirstEnumType type) { this.helperFirstCalcBll(type); } public void Meth(SecondEnumType type) { this.helperSecondCalcBll(type); } 

3 Comments

It says "Cannot convert type to <...enumname...>"
Updated answer with a better solution given the simplicity of the request.
@RobertMcKee That's the best solution if you have a method; however, for me it's not clear if our OP has a constructor or a method (his current code is incorrect :-) ).
4

This is something dynamic is very useful for:

public void Meth<T>(T enumValue) where T : struct { InternalMeth((dynamic)enumValue); } private void InternalMeth(FirstEnumType enumValue) { this.helperFirstCalcBll(enumValue); } private void InternalMeth(SecondEnumType enumValue) { this.helperSecondCalcBll(enumValue); } private void InternalMeth(object enumValue) { // Do whatever fallback you need } 

This avoids having to write all those if (typeof(T) == typeof(...)) and everything - you let the dynamic dispatch handle picking the best overload at runtime. The object overload is there if all the others fail, so that you can e.g. throw an exception.

2 Comments

Might not want to use enum; enum is a reserved keyword
@atlaste Good point. I tend to forget which keywords are reserved and which are context-sensitive :))
0

Try defining a helper method:

private TOutput Convert<TInput, TOutput>(TInput value) where TInput : struct where TOutput : struct { var matchingValues = Enum.GetValues(typeof(TOutput)) .Cast<int>() .Where(v => System.Convert.ToInt32(value) == v); if(!matchingValues.Any()) { var message = String.Format("No matching value found in enum '{0}' for value '{1}'.", typeof(TOutput).Name, value); throw new ArgumentException(message); } var obj = (object)matchingValues.Single(); return (TOutput)obj; } 

This would convert values of two enums given that there is a value in the output enum that equals the input value.

And in your code you would call it as follows:

public Meth<T> (T type) { if (typeof(T) == typeof(FirstEnumType)) { FirstEnumType t = Convert(type); this.helperFirstCalcBll(t); } else { SecondEnumType t = Convert(type); this.helperSecondCalcBll(t); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.