如何限制通用参数来实现基本的数学运算符?
问题描述:
有没有办法做到这一点?如何限制通用参数来实现基本的数学运算符?
我想有一个T的集合类,它能够在T类型上进行加法,减法。我想保持T泛型,而不是使用相同的代码,但不同类型的夫妇集合。
你会如何约束泛型T?
例如:我想定义一个Collection(T为IDoMaths)。我不想用命名方法创建自己的整数等类来完成这些操作,因为我认为它会变慢。这部分代码实际上经常被调用,并且往往是性能的瓶颈。
答
不幸的是,你不能。
有一种解决方法,Marc Gravell将implemented作为MiscUtil的一部分(也有more general article)。它很整洁,但你确实失去了静态类型检查。
与此类似(失去类型检查换算)为C#4.0新dynamic
功能可让您使用运营商以任意方式,只有在执行时解决这些问题:
dynamic x = 10.0;
dynamic y = 3.0;
double z = x/y; // z = 3.3333333 (double arithmetic)
dynamic a = 10;
dynamic b = 3;
int c = a/b; // c = 3 (integer arithmetic)
就在今天下午我用它来实现Enumerable.Sum
的动态表单。我即将对它进行基准测试。 Marc Gravell最近也写了一篇关于这个的blog post。
如果您使用的是VB,可能只需将代码段的Option Strict
关闭,您希望后期绑定会产生相同的效果,但我不熟悉VB,因为我使用C#,I '我害怕。
答
如果你想要一个更直接,但涉及多一点冗余的替代解决方案,你可以尝试一些我刚刚掀起来的东西。这里的一个优点是它完全类型安全。
这是一个快速的脏版本,它为int和float实现了+和 - 操作。将它扩展到包含更多的操作以及支持更多的原始类型(双精度,十进制等)或甚至自定义类型都应该是微不足道的。只需用您需要的任何东西替换GenericMath即可。
class Program
{
static void Main(string[] args)
{
var gsInt = new GenericMath<int,IntOperators>();
var gsFloat = new GenericMath<float,FloatOperators>();
var intX = gsInt.Sum(2, 3);
var floatX = gsFloat.Sum(2.4f, 3.11f);
}
}
interface IOperators<T>
{
T Sum(T a, T b);
T Difference(T a, T b);
}
sealed class IntOperators : IOperators<int>
{
public int Sum(int a, int b) { return a + b; }
public int Difference(int a, int b) { return a - b; }
}
sealed class FloatOperators : IOperators<float>
{
public float Sum(float a, float b) { return a + b; }
public float Difference(float a, float b) { return a + b; }
}
class GenericMath<T,Y>
where Y : IOperators<T>, new()
{
private readonly static Y Ops = new Y();
public T Sum(T a, T b)
{
return Ops.Sum(a, b);
}
public T Difference(T a, T b)
{
return Ops.Difference(a, b);
}
}
这是一个令人失望的限制,在当前泛型的实现。马克的实施是我见过的最好的处理问题。有关connect.microsoft.com的一些支持文章与此相关。你可以在这里找到它们:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94264和这里:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID= 325177和这里:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=338861。 – LBushkin 2009-05-27 21:23:35
你是否打算使用动态的int示例? – 2009-05-27 21:47:50