有没有办法可以做到这一点?
我想有一个T类的集合类,可以在T类型上进行加法,减法。我想保持T泛型,而不是让几个集合具有相同的代码,但不同的类型。
你如何约束通用T?
示例:我想定义一个Collection(T作为IDoMaths)。我不想用命名方法创建我自己的整数等类来进行操作,因为我觉得它会慢一些。这部分代码实际上经常被调用,并且往往是性能的瓶颈。
答案 0 :(得分:7)
不幸的是你不能。
有一种解决方法,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#,我很害怕。
答案 1 :(得分:4)
如果您想要一种更直接但又需要更多冗余的替代解决方案,您可以尝试一些我刚刚开始尝试的方法。这里的一个优点是它完全是类型安全的。
这是一个快速的脏版本,它实现了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 );
}
}