2010-09-28 18 views

Respuesta

23

poco de un truco, pero ...

Usted puede proporcionar sobrecargas de operadores en su clase base que luego llamar a algunos métodos abstractos publicados en una de las clases para hacer el trabajo allí.

public abstract class MyClass 
{ 
    public static MyClass operator +(MyClass c1, MyClass c2) 
    { 
     return c1.__DoAddition(c2); 
    } 

    protected abstract MyClass __DoAddition(MyClass c2); 
} 
+1

'abstract protected' en lugar de' private abstract', supongo .. – abatishchev

+1

No es bueno, pero es efectivo. También lo estoy haciendo de esta manera. – elsni

+0

@abatishchev: gracias, gracias :) – Codesleuth

8

No. La única forma sensata de hacer esto sería hacer que un test de prueba de unidad use la reflexión para encontrar todas las implementaciones concretas, y luego verificar esta condición. Puede también hacer algo en el tiempo de ejecución re lo mismo a través de un constructor estático, pero entonces la pregunta es que constructor estático?

Otro enfoque es abandonar los operadores y utilizar un enfoque basado en interfaz; por ejemplo, si necesita T para tener +(T,T), en lugar de que los operadores tengan una interfaz con un método Add(T). Otra ventaja aquí es que las interfaces se pueden usar desde genéricos (generalmente a través de restricciones), donde-como el uso de operadores de código genérico requiere un poco de esfuerzo.

+1

métodos utilizando como sumar, restar es próxima elección obvia pero desde mi código tendrá muchos cálculos como 's = s1 * 2 + s2 * s3 - s4 * (s5 - s6);'. El uso de métodos lo hará 's = s1.Multiplicar (2) .Add (s2.Multiplicar (s3)). Restar (s4.Multiplicar (s5.Subtract (s6)));' ¡Ciertamente no muy legible! – Hemant

+0

@Hemant: Puede usar el apóstrofo 'para resaltar el código en los comentarios también – abatishchev

+0

@abatishchev solucionó eso; p –

5

Puede implementar la sobrecarga en una clase base abstracta, pero delegue los detalles de la operación real en un método abstracto. Entonces esto tendrá que implementarse y la sobrecarga se aplicará con su implementación.

public abstract class OverLoadingBase 
{ 
    public abstract OverLoadingBase DoAdd(OverLoadingBase y); 

    public static OverLoadingBase operator +(OverLoadingBase x, OverLoadingBase y) 
    { 
     return x.DoAdd(y); 
    }  
} 

Aunque no estoy seguro de si esto está completo.

+0

@abatishchev - Tengo curiosidad - ¿por qué cambia el formato de la llave? –

1

Como su operador solo se puede sobrecargar y no anular, es bastante difícil. La mejor solución que puedo pensar es utilizar una clase abstracta y sobrecargarla así.

public abstract class MyBase 
{ 
    public abstract MyBase Add(MyBase right); 
    public abstract MyBase Subtract(MyBase right); 

    public static MyBase operator +(MyBase x, MyBase y) 
    { 
     //validation here 
     return x.Add(y); 
    } 

    public static MyBase operator -(MyBase x, MyBase y) 
    { 
     //validation here 
     return x.Subtract(y); 
    } 
} 
3

he hecho esto en el pasado ...

public abstract class BaseClass<TClass> where TClass : BaseClass 
{ 
    public static TClass operator +(TClass c1, TClass c2) 
    { 
     return c1.DoAddition(c2); 
    } 

    protected abstract TClass DoAddition(TClass c2); 
} 

Y luego implementado de la siguiente manera:

public class ConcreteClass : BaseClass<ConcreteClass> 
{ 
    protected ConcreteClass DoAddition(ConcreteClass c2) 
    { 
     ... 
    } 
}