简体   繁体   中英

How can I implement a method with a generic parameter (constrained to an integer type) with a cast?

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)?

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM