C # Operadores generics

Estoy tratando de implementar un operador genérico como ese:

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

Realmente lo que estoy tratando de hacer es manejar con gracia la herencia. Con un operador estándar + en Foo, donde T es en cambio “Foo”, si alguien se deriva de Foo (digamos que Bar hereda Foo), entonces una operación Bar + Bar aún devolverá un Foo. Tenía la esperanza de resolver esto con un operador genérico +, pero acabo de obtener un error de syntax para el anterior (en el <) haciéndome creer que dicho código no es legal.

¿Hay alguna manera de hacer un operador genérico?

No, no puedes declarar operadores generics en C #.

Los operadores y la herencia en realidad no se mezclan bien.

Si desea que Foo + Foo devuelva un Foo y Bar + Bar para devolver un Bar, tendrá que definir un operador en cada clase. Pero, dado que los operadores son estáticos, no obtendrás los beneficios del polymorphism porque el operador a llamar se decidirá en tiempo de comstackción:

 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 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 add = Expression.Lambda>(body, paramA, paramB).Compile(); // call it return add(a,b); } 

Puedes simplemente definir operador en una clase genérica Foo.

También puede crear operadores generics reales, pero el comstackdor de C # no los usará.

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

No se pueden declarar operadores generics en C #: no estoy seguro del razonamiento, pero supongo que es una utilidad versus esfuerzo para el equipo de implementación (creo que podría haber una publicación aquí con Jon Skeet discutiéndola, o quizás en su blog cuando él discutió cosas que le gustaría ver en C #).

De hecho, ni siquiera puede usar operadores con generics en C #.

Esto se debe a que los generics deben ser aplicables para todos los tipos posibles que podrían proporcionarse. Es por eso que debe aplicar el scope del tipo genérico a las clases cuando desee utilizar == como se muestra a continuación:

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

Lamentablemente no puedes hacer:

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

También podría estar interesado en este breve artículo de resumen que encontré.

Estaba buscando lo mismo y google me trajo aquí … No estaba muy contento con la respuesta aceptada y estaba buscando una solución alternativa.

Logré implementar esto usando generics. Aquí está la clase Foo y 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; } } 

Luego, una clase genérica que contiene los operadores, pero restringida al tipo de Foo y derivada de Foo:

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

Algunos códigos de uso que le muestran que siempre recupera un Foo y le impide mezclar los tipos:

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