Generics are useful for writing code that works with any type (possibly using some interface that can be specified using where ). However, if you want to use them to implement a method that can return two different numeric types, it feels a little wrong (it will only work if double and decimal have some common interfaces implemented).
You should probably define two different methods (e.g. ComputePercentage and ComputePercentagePrecise or something similar - since you cannot use overload using different parameters).
It may be possible to get around this limitation using something like this (but this is probably too complicated for you):
class INumericOps<T> { public abstract T One { get; } public abstract T Add(T a, T b);
Then you should write a method that takes INumericOps<T> as a type parameter and uses it to do all the math inside the method:
private static R ComputePercentage<T, R>(ushort level, ushort capacity) where T : INumericOps<R>, where T : new() { INumericOps<R> ops = new T();
Then you would call it like this:
decimal res = ComputePercentage<DecimalNumerics, decimal>(...);
This is a good trick, and it is probably the best (safe type) workaround you can get. However, this is a bit complicated, so declaring two separate methods might be a better idea.
Tomas petricek
source share