设计对泛型数学接口有约束的泛型类型

Designing generic types with constraints on generic math interfaces

提问人:Matthew Layton 提问时间:3/5/2023 更新时间:6/21/2023 访问量:77

问:

请考虑以下简单示例,该示例是一个表示 .ISignedNumber<T>

public readonly struct Square<T> where T : ISignedNumber<T>
{
    public Square(T value)
    {
        Value = value * value;
    }
    
    public T Value { get; }
}

Square<int> a = new(123);
Console.WriteLine(a.Value); // 15129

Square<long> b = new(1234567);
Console.WriteLine(b.Value); // 1524155677489

Square<BigInteger> c = new(BigInteger.Parse("123456789000000000"));
Console.WriteLine(c.Value); // 15241578750190521000000000000000000

值得注意的是,此实现将适用于任何实现 ,因为这是可能的。ISignedNumber<T>value * value

不那么琐碎的是如何构建需要已知常量先验知识的结构;例如,我可能想要构建一个表示给定数字的黄金比例的结构,这需要了解 Phi

(phi): φ = (1 + sqrt(5)) / 2 ≈ 1.61803398875

由于此值是常量文本,因此无法应用。where T : IFloatingPoint<T>

public readonly struct GoldenRatio<T> where T : IFloatingPoint<T>
{
    public static T Phi = 1.61803398875;
}

无法将源类型“double”转换为目标类型“T”

虽然我认为答案很简单,这不可能用通用数学接口实现,但我想我还是会在这里问,以防万一我忽略了什么。

我唯一能想到的是,当创建实例时,必须根据所选类型传入值;即 , , , ,但这最终会限制类型只允许一组有限的实现,并且在运行时,这不是很好。GoldenRatio<T>floatdoubledecimalIFloatingPoint<T>

C# 浮点 .net-generic-math

评论

0赞 Guru Stron 6/21/2023
另请查看如何使用泛型数学生成常量值在泛型数学 C# 11 中使用数值文字/常量

答:

1赞 shingo 3/5/2023 #1

您可以使用一些创建函数从浮点数进行转换。

public readonly struct GoldenRatio<T> where T : IFloatingPoint<T>
{
    public static readonly T Phi = T.CreateChecked(1.61803398875);
}