C#generics操作符

我想要实现一个通用的运算符,如下所示:

class Foo { public static T operator +<T>(T a, T b) { // Do something with a and b that makes sense for operator + here } } 

真的,我想要做的是优雅地处理inheritance。 用Foo中的标准操作符+,T代替“Foo”,如果有人是从Foo派生的(比如BarinheritanceFoo),那么Bar + Bar操作仍然会返回Foo。 我希望用一个通用的operator +来解决这个问题,但是我刚刚得到了一个语法错误(在<)使我相信这样的代码是不合法的。

有没有办法做一个通用的运营商?

不,你不能在C#中声明generics操作符。

运营商和inheritance不太好混合。

如果你想让Foo + Foo返回一个Foo和Bar + Bar来返回一个Bar,你将需要在每个类上定义一个操作符。 但是,由于运算符是静态的,因此不会得到多态性的好处,因为调用哪个运算符将在编译时决定:

 Foo x = new Bar(); Foo y = new Bar(); var z = x + y; // calls Foo.operator+; 

http://www.yoda.arachsys.com/csharp/genericoperators.html

 static T Add<T>(T a, T b) { //TODO: re-use delegate! // declare the parameters ParameterExpression paramA = Expression.Parameter(typeof(T), "a"), paramB = Expression.Parameter(typeof(T), "b"); // add the parameters together BinaryExpression body = Expression.Add(paramA, paramB); // compile it Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile(); // call it return add(a,b); } 

您可以在generics类Foo中定义运算符。

你也可以创build真正的generics操作符,但是C#编译器不会使用它们。

 [System.Runtime.CompilerServices.SpecialName] public static T op_Addition<T>(T a, T b) { ... } 

你不能在C#中声明generics操作符 – 我不确定推理是什么,但是认为这对于实现团队来说是一个有用的工作。我相信Jon Skeet可能会在这里发布一个post,或者在他的博客上讨论他希望在C#中看到的东西)。

事实上,你甚至不能在C#中使用generics操作符。

这是因为仿制药必须适用于所有可能提供的种类。 这就是为什么当你想使用==时,你必须将genericstypes的范围设置为类,如下所示:

 void IsEqual<T>(T x, T y) where T : class { return x == y; } 

不幸的是你不能这样做:

 void Add<T>(T x, T y) where T : operator + { return x + y; } 

您可能也会对我遇到的这篇简短的摘要文章感兴趣。

正在寻找相同的东西,谷歌把我带到这里….我不是太高兴,接受的答案,并寻找一个解决方法。

我设法实现这个使用generics。 这是Foo和Bar类:

  class Foo { private int value; public Foo(int x) { value = x; } public virtual int getVal() { return value; } } class Bar : Foo { private int derivedValue; public Bar(int x):base(x) { derivedValue = x; } public override int getVal() { return derivedValue; } } 

然后是一个包含运算符但限于Footypes并从Foo派生的generics类:

  class GenericOp<T> where T : Foo { private T value; public GenericOp(T x) { value = x; } public static Foo operator +(GenericOp<T> a, GenericOp<T> b) { return new Foo(a.value.getVal() + b.value.getVal()); } } 

一些使用代码显示你总是得到Foo以及阻止你混合types:

 Foo f1 = new Foo(1); Foo f2 = new Foo(2); Bar b1 = new Bar(10); Bar b2 = new Bar(20); GenericOp<Foo> left = new GenericOp<Foo>(f1); GenericOp<Foo> right = new GenericOp<Foo>(f2); Foo res = left + right; GenericOp<Bar> left1 = new GenericOp<Bar>(b1); GenericOp<Bar> right1 = new GenericOp<Bar>(b2); Foo res1 = left1 + right1; GenericOp<Foo> left2 = new GenericOp<Foo>(f1); GenericOp<Bar> right2 = new GenericOp<Bar>(b1); //Foo res2 = left2 + right2; //this fails and rightfully so.