如何将 INumber<T> 与 int 相乘?

问题描述 投票:0回答:3

如何在最后一行实现 int (

z * 2
) 的乘法?

public static TResult Test<TResult>() where TResult : INumber<TResult>
{
    TResult x = TResult.AdditiveIdentity;
    TResult y = TResult.MultiplicativeIdentity;
    TResult z = x * y;
    TResult z2 = z * 2; // <--- this gives the CS0019 error "The operator * cannot be applied to operands of type 'TResult' and 'int'
    return z2;
}

--- 建议的解决方案是添加一个接口,但它打破了这一点:

IMultiplyOperators<TResult, int, TResult>

public static void Tester()
{
    Test<decimal>(); // CS0315 Tye type decimal cannot be used as type parameter TResult..... there is no boxing conversion
}

现在我将自己注入该函数并使用:

public static TResult Test<TResult>(Func<TResult, int, TResult> mul) where TResult : INumber<TResult>
{
    TResult x = TResult.AdditiveIdentity;
    TResult y = TResult.MultiplicativeIdentity;
    TResult z = x * y;
    TResult z2 = mul(z, 2);
    return z2;
}
c# math numbers .net-7.0
3个回答
16
投票

我建议 转换

2
TResult
然后再相乘:

   TResult z2 = z * TResult.CreateChecked(2);

这里我们从整数值

TResult
创建
2
实例,同时检查
2
是否存在溢出和类似的可能错误(如果
2
无法转换为
TResult
,则会抛出异常:要么
 OverflowException
NotSupportedException
)。

代码:

public static TResult Test<TResult>() where TResult : INumber<TResult>
{
    TResult x = TResult.AdditiveIdentity;
    TResult y = TResult.MultiplicativeIdentity;
    TResult z = x * y;
    TResult z2 = z * TResult.CreateChecked(2);
    return z2;
}

演示:

Console.WriteLine(Test<decimal>());

输出:

0

小提琴


9
投票

需要添加

IMultiplyOperators<, ,>
接口:

public static TResult Test<TResult>() where TResult : INumber<TResult>, IMultiplyOperators<TResult, int, TResult>
{
    TResult x = TResult.AdditiveIdentity;
    TResult y = TResult.MultiplicativeIdentity;
    TResult z = x * y;
    TResult z2 = z * 2;
    return z2;
}

您可以在此处查看操作员界面列表。


3
投票

虽然不是通用解决方案,但在这种情况下(乘数 = 2)您可以简单地写:

TResult z2 = z + z;

除了 z 是 TResult.AdditiveIdentity * TResult.MultiplicativeIdentity。但 TResult.AdditiveIdentity 为零。所以结果将为零。

© www.soinside.com 2019 - 2024. All rights reserved.