c# - 我怎样才能把这个简单的方法变成一个通用的方法?
问题描述
我有一个方法如下:
int coerce(int val, int min=0, int max = 10)
{
if (val < min)
return min;
if (val > max)
return max;
return val;
}
现在,我必须将其用于byte
、float
、double
和其他数字类型。
众所周知,为这些类型制作许多类似的方法是非常无效的,所以我想把它变成一个泛型方法。以下是我尝试做的事情:
T coerce<T>(T val, T min=(T)0, T max=(T)10) where T:IComparable
{
// ... same as the above ...
}
我知道代码没有运行,这就是我要求这个的原因。我目前对两个问题感到困惑:
如何比较
T
类型?Visual Studio 会警告操作员
<
和>
. 我尝试使用where T:IComparable
,但它并没有解决我的问题。如何为泛型参数设置默认值?
我尝试使用
(T)0
它(T)10
。但无论如何,这不是一个好的选择。
这可能是一个简单的问题,但我无法从谷歌找到答案。
解决方案
您应该使用Compare
方法而不是<
或>
运算符。并应用正确的通用约束,对于数字类型它应该是IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
. 但是,您可以只留下where T : struct, IComparable<T>
,它应该足以满足您的目的(但struct
在这里很重要,因为您正在比较值类型)
T coerce<T>(T val, T min, T max) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{
if (val.CompareTo(min) < 0)
return min;
if (val.CompareTo(max) > 0)
return max;
return val;
}
您还可以指定默认min
值,例如T min = default(T)
,但您不能为max
value 这样做。
在注释之后,如果使用Nullable<T>
formin
和max
values 代码可以写成
T coerce<T>(T val, T? min = default, T? max = default) where T : struct, IComparable<T>
{
var minValue = min.HasValue ? min.Value : default(T);
var maxValue = max.HasValue ? max.Value : (T)Convert.ChangeType(10, typeof(T));
if (val.CompareTo(minValue) < 0)
return minValue;
if (val.CompareTo(minValue) > 0)
return maxValue;
return val;
}
推荐阅读
- sockets - 如何在不知道 C++ 中的服务器端口的情况下在连接到服务器和服务器 ip 的接口上发送 udp 数据包
- ajax - 如何将左连接值添加到 ajax 中生成的 html 表
- jboss - 在流口水如何处理对事实模式的动态更改
- c# - aspx.vb 页面中的 ASP.NET VB WebMethod - 失败但在 C# 中有效
- javascript - Chrome 85 Service Worker 一直在尝试安装
- concurrency - Elixir/Erlang 并发状态访问
- javascript - Angular - 从另一个滑块更新滑块的值
- android - 将图像添加到 Android Studio 项目
- python-3.x - 我应该如何在 python 中使用 atexit?
- php - .htaccess 文件重写,不要从 seo 友好的 url 获取参数