[英]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). 类型
T
将是System.UInt32
, System.UInt64
(但可能更多)。
Or will I have to implement each type of ISqrtN
separately (overloading)? 还是我必须分别实现每种
ISqrtN
类型(重载)?
C# has no support for generic numerics. C#不支持通用数字。 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. 然后,IntelliSense将显式显示允许的参数类型。 This is what the
Math
class does for the Abs
or Max
for example. 例如,这就是
Math
类对Abs
或Max
的作用。
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. 首选的解决方案是根本不使用通用方法,因为您不能将
T
限制为可以防止人们调用ISqrtN<DateTime>
等的类型。
Workarounds that maintain the generic method signature are either using dynamic
runtime binding: 维护通用方法签名的解决方法是使用
dynamic
运行时绑定:
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. 要求进行中间
(object)
强制转换,因为C#不允许从T
直接转换为uint
,但是它们在运行时不会有所作为。
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. 最好的办法是对
where T : struct
的值类型使用通用类型约束,但这将允许发送任何结构。 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. 如果您确实希望对
uint
和ulong
施加约束,那么我建议您将原始实现保留为私有方法,并仅创建其他2个公共方法,每个公共方法针对您要支持的类型,然后将它们称为私有方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.