在。net 7中,有IFloatingPoint
。我阅读了。net 6的以下代码。它使用struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
。所有这些约束都是必要的吗?
代码:
using System;
namespace MyExtensions
{
public static class NumericExtensions
{
public static T Round<T>(this T value, int decimalPlaces) where T :
struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
decimal decimalValue = Convert.ToDecimal(value);
decimal rounded = Math.Round(decimalValue, decimalPlaces);
return (T)Convert.ChangeType(rounded, typeof(T));
}
}
}
舍入只对浮点数有意义。在c#中,我们只有三种类型的浮点数(float
,double
,decimal
)。Math.Round
方法有两个变体,一个用于double
,一个用于decimal
。两者在内部使用不同的舍入算法。对小数的双精度使用舍入方法,反之亦然,都可能导致意想不到的结果。
由于我们只有三个相关的类型,生成扩展方法的最简单方法是为每个类型编写一个扩展方法。每个类型一行就足够了:
public static class NumericExtensions
{
public static double Round(this double value, int decimalPlaces) => Math.Round(value, decimalPlaces);
public static decimal Round(this decimal value, int decimalPlaces) => Math.Round(value, decimalPlaces);
public static float Round(this float value, int decimalPlaces) => (float)Math.Round(value, decimalPlaces);
}
从。net 7开始,框架中的数字类型被扩展为实现泛型接口,这使得编写处理数字的泛型方法变得更加容易。现在浮点类型本身也有Round()
方法,所以我们不必再使用Math.Round()
,而是可以使用实际类型的Round()
方法。
Half
类型)的扩展方法:
public static class NumericExtensions
{
public static T Round<T>(this T value, int decimalPlaces) where T : IFloatingPoint<T> => T.Round(value, decimalPlaces);
}
- 微软博客文章关于。net 7中数字类型的新泛型能力