Reputation: 500
I basically want this to compile:
T ISqrtN<T>(T N) => (T)Math.Sqrt((double)N);
The type T
will be one of System.UInt32
, System.UInt64
(but possibly more).
Or will I have to implement each type of ISqrtN
separately (overloading)?
Upvotes: 0
Views: 57
Reputation: 1196
Overload resolution is performed at compile time, even for generic methods. The preferred solution would be to not use a generic method here at all, since you can't constrain T
to types that work to prevent people from calling ISqrtN<DateTime>
etc.
Workarounds that maintain the generic method signature are either using dynamic
runtime binding:
T ISqrtN<T>(T N) => (T)Math.Sqrt((dynamic)N);
or manually type-checking and casting to specific supported types:
T ISqrtN<T>(T N)
{
if (typeof(T) == typeof(uint))
return (T)(object)(uint)Math.Sqrt((uint)(object)N);
else if (typeof(T) == typeof(ulong))
return (T)(object)(ulong)Math.Sqrt((ulong)(object)N);
else
throw new ArgumentException();
}
The intermediate (object)
casts are required because C# won't allow a direct cast from T
to uint
, but they won't make a difference at runtime.
Upvotes: 1
Reputation: 112402
C# has no support for generic numerics. There is no common numeric base type and there is no interface declaring the basic numeric operations. The easiest way to go, is to user overloads
uint ISqrtN(uint N) => (uint)Math.Sqrt((double)N);
ulong ISqrtN(ulong N) => (ulong)Math.Sqrt((double)N);
Then IntelliSense will show you the allowed parameter types explicitly. This is what the Math
class does for the Abs
or Max
for example.
Upvotes: 2
Reputation: 2029
You would have to implement them separately. The best you could do is to use a generic type constraint to a value type where T : struct
but this would allow any struct to be sent.
If you really want to have that constraint on uint
and ulong
I would recommend keeping your original implementation as a private method and just create other 2 public methods, each one for the type you want to support, and make them call the private method.
Upvotes: 0