我最近遇到了这个问题,我想要一个函数来处理双精度和整数,并且想知道为什么所有数字类型都没有通用接口(包含算术运算符和比较).
它会使编写函数Math.Min
(存在于无数的重载中)更方便.
引入一个额外的接口是一个突破性的变化吗?
编辑: 我想考虑使用这个
public T Add<T>(T a, T b) where T: INumber
{
return a+b;
}
Run Code Online (Sandbox Code Playgroud)
要么
public T Range<T>(T x, T min, T max) where T:INumber
{
return Max(x, Min(x, max), min);
}
Run Code Online (Sandbox Code Playgroud)
如果你想做这种"通用"算术,你选择强类型语言如C#是非常有限的.Marc Gravell 将问题描述如下:
.NET 2.0在.NET世界中引入了泛型,为现有问题的许多优雅解决方案打开了大门.通用约束可以用来限制类型参数已知接口等,以确保获得的功能-或者简单的等号/不等测试
Comparer<T>.Default
和EqualityComparer<T>.Default
单身落实IComparer<T>
和IEqualityComparer<T>
分别(让我们的实例中的元素进行排序,而无需知道什么有问题的"T").尽管如此,在运营商方面仍存在很大差距.因为运算符被声明为静态方法,所以没有
IMath<T>
或类似的所有数值类型实现的等效接口; 事实上,运营商的灵活性会使这项工作变得非常困难.更糟糕的是:原始类型的许多运算符甚至不作为运算符存在; 相反,有直接的IL方法.为了使情况更加复杂,Nullable <>要求"提升运算符"的概念,其中内部"T"描述适用于可空类型的运算符 - 但这是作为语言特征实现的,并不是由运行时(使反射更有趣).
但是,C#4.0引入了一个dynamic
关键字,您可以使用该关键字在运行时选择正确的重载:
using System;
public class Program
{
static dynamic Min(dynamic a, dynamic b)
{
return Math.Min(a, b);
}
static void Main(string[] args)
{
int i = Min(3, 4);
double d = Min(3.0, 4.0);
}
}
Run Code Online (Sandbox Code Playgroud)
您应该知道这会消除类型安全性,如果动态运行时无法找到合适的调用重载,您可能会在运行时获得异常,例如因为您混合了类型.
如果您想获得类型安全性,您可能需要查看MiscUtil库中可用的类,为基本操作提供通用运算符.
请注意,如果您仅在特定操作之后,实际上可能使用内置类型已实现的接口.例如,类型安全的泛型Min
函数可能如下所示:
public static T Min<T>(params T[] values) where T : IComparable<T>
{
T min = values[0];
foreach (var item in values.Skip(1))
{
if (item.CompareTo(min) < 0)
min = item;
}
return min;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5815 次 |
最近记录: |