Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I multiply a INumber<T> with an int? [duplicate]

How should I implement the multiplication by int (z * 2) on the last line?

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;
}

--- the suggested solution is to add an interface, but it breaks this: 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
}

For now I will inject the function myself and use:

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;
}
like image 796
Wouter Avatar asked Nov 20 '25 05:11

Wouter


1 Answers

I suggest converting 2 to TResult and only then multiply:

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

Here we create TResult instance from integer value 2, while checking 2 for overflow and similar possible errors (an exception will be thrown if 2 can't be converted into TResult: either OverflowException or NotSupportedException).

Code:

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;
}

Demo:

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

Output:

0

Fiddle

like image 135
Dmitry Bychenko Avatar answered Nov 21 '25 17:11

Dmitry Bychenko