我基本上希望它可以编译:
T ISqrtN<T>(T N) => (T)Math.Sqrt((double)N);
类型T
将是System.UInt32
,System.UInt64
中的一种(但可能更多)。
还是我必须分别实现每种类型的ISqrtN
(超载)?
答案 0 :(得分:2)
C#不支持通用数字。没有通用的数字基类型,也没有接口声明基本的数字运算。最简单的方法是让用户超载
uint ISqrtN(uint N) => (uint)Math.Sqrt((double)N);
ulong ISqrtN(ulong N) => (ulong)Math.Sqrt((double)N);
然后,IntelliSense将显式显示允许的参数类型。例如,Math
类就是为Abs
或Max
做的。
答案 1 :(得分:1)
重载解析在编译时执行,即使对于通用方法也是如此。首选的解决方案是根本不使用通用方法,因为您不能将enter code here
限制为可以防止人们调用T
等的类型。
维护通用方法签名的变通办法是使用ISqrtN<DateTime>
运行时绑定:
dynamic
或手动进行类型检查并强制转换为特定的受支持类型:
T ISqrtN<T>(T N) => (T)Math.Sqrt((dynamic)N);
由于C#不允许直接从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();
}
到(object)
进行强制转换,因此需要进行中间T
强制转换,但它们在运行时不会有所不同。
答案 2 :(得分:0)
您将不得不分别实现它们。最好的办法是对值类型where T : struct
使用泛型类型约束,但这将允许发送任何结构。
如果您确实想对uint
和ulong
施加约束,我建议您将原始实现保留为私有方法,并仅创建其他2个公共方法,每个公共方法都针对您要支持的类型,并且让他们调用私有方法。