2009-11-13 19 views
6

Una cuestión conceptual:Sobrecarga del operador en C# - ¿A dónde debe ir el código de código real?

Estoy creando mi estructura personalizada, en la línea de un Vector3 (3 valores int) y estaba trabajando sobrecargando los operadores estándar (+, -, *, /, == etc ...)

Como estoy construyendo una biblioteca para uso externo, intento cumplir con las reglas de FxCop. Como tal, recomiendan tener métodos que realicen la misma función.

Por ejemplo. .Add(), .Subtract(), etc ...

Para ahorrar en la duplicación de código, uno de estos métodos (la sobrecarga del operador o el método real) va a llamar al otro.

Mi pregunta es, ¿cuál debería llamar a cuál?

¿Es (y esto no es más que un código de ejemplo):

A)

public static MyStruct operator +(MyStruct struc1, MyStruct struct2) 
    { 
     return struc1.Add(struct2); 
    } 

    public MyStruct Add(MyStruct other) 
    { 
     return new MyStruct (
      this.X + other.X, 
      this.Y + other.Y, 
      this.Z + other.Z); 
    } 

o:

B)

public static MyStruct operator +(MyStruct struc1, MyStruct struct2) 
    { 
     return new MyStruct (
      struct1.X + struct2.X, 
      struct1.Y + struct2.Y, 
      struct1.Z + struct2.Z); 
    } 

    public MyStruct Add(MyStruct other) 
    { 
     return this + other; 
    } 

Realmente no estoy seguro cualquiera es preferible, pero estoy buscando algunas opiniones :)

+1

¿Por qué hizo que los métodos basados ​​en instancias en lugar de estáticos con dos parámetros? ¿Es eso lo que FxCop recomienda? –

Respuesta

24

Me gustaría ir con A). Debido a que la sobrecarga del operador no es compatible con CLS (no todos los idiomas .NET soportan operadores de sobrecarga) se puede considerar como azúcar sintáctico alrededor del método de adición real.

+0

Ah, no me di cuenta de que la sobrecarga del operador no cumple con la CLI. A) es entonces. ¡Gracias! –

+1

El hecho de que no es compatible con CLI no significa que el dll compilado no funcionaría con otros idiomas. – Dykam

+0

@Dykam: Por supuesto que no, pero sus clientes tendrían que escribir algo como 'MyStruct.op_Addition (myStruct1, myStruct2)' si usa un lenguaje CLI que no admita la sobrecarga del operador para +. – bitbonk

0

Yo votaría por la opción B, ya que es el lugar más intuitivo que hay que mirar cuando se observa qué valores/propiedades se están utilizando realmente en el operador.

3

Cualquiera. Realmente no importa. Esperaría que el código se inserte de todos modos, así que ve con lo que consideres más legible.

+1

pero eso es exactamente lo que pregunta ... ¿qué creemos que es más legible – Letterman

1

Dado que es un struct, la herencia no es un problema (de otro modo "A" hace más fácil virtual) - por lo que iría con "B", simplemente porque espero que llamar + más de lo que llamo Add ... menos indirección

Para una class con una necesidad real de + y herencia (improbable), iría "A".

2

Definitivamente A.

Los métodos son reales. El método puede obtener params adicionales, se pueden marcar como virtuales (=> se pueden reemplazar), sobrecargados, y generalmente son más la naturaleza del idioma. Antes de buscar una razón práctica, creo que debes sentirlo. además, el protocolo de lenguaje CIL no es vinculante para soportar la sobrecarga del operador, y ese tipo de victoria clara para el método.

0

También iría con A por muchos de los motivos indicados anteriormente, en particular porque veo la sobrecarga del operador como un mecanismo de sintaxis que está envolviendo el método real.