2009-10-31 14 views
5

¿Es esta una restricción de CLR o una decisión de diseño de idioma? Traté de hacerlo en C++/CLI, por supuesto, donde funciona debido a la necesidad de apoyar nativo de C++:¿Por qué C# no admite la sobrecarga del operador con pase por referencia?

public ref class Test 
    { 
     public: 
     static Test^ operator &(Test^ msg, int& i) 
     { 
      i = i + 1; 

      return nullptr; 
     } 
    }; 

y luego miró el compilador de salida omitido:

public: static Test __gc* op_BitwiseAnd(Test __gc* msg, Int32 __gc** modopt(IsImplicitlyDereferenced __gc*) i) 
{ 
    i[0] += 1; 
    return 0; 
} 

fui más allá y traté de llamar a este operador del proyecto de C# - y por supuesto que tenía que ir [inseguro] para hacerlo (necesitaba puntero):

Test t = new Test(); 
int i = 0; 

unsafe 
{ 
    t = t & &i; 
} 

Obviamente no es tan difícil de implementar para el CLR? Realmente echo de menos pasar por referencia en la sobrecarga de los operadores y me gustaría, al menos a la luz, saber por qué falta esto.

¿Por qué C no puede ocultar la fealdad detrás de lo inseguro y los indicadores cuando tenemos que tratar con variables de referencia en nuestras sobrecargas de operador? Incluso si eligiera esta fea solución, no funcionaría en Silverlight, donde las operaciones inseguras no están permitidas ...

Respuesta

5

En C#, sus variables nunca son alteradas por las calles sin que usted las transmita explícitamente como referencias (ej. int.TryParse(s, out i) donde especifica explícitamente la palabra clave out). Esta característica complicaría las cosas al permitir que el operador sobrecargado altere el contenido de los operandos sin su permiso explícito.

Por ejemplo,

public static MyStruct operator + (ref MyStruct left, ref MyStruct right) { 
    left = new MyStruct(); // !!!!!!!! 
    return something(left, right); 
} 

Cuando hace referencia a un operador como en C#:

MyStruct x = new MyStruct(); 
MyStruct y = new MyStruct(); 
MyStruct z = x + y; // in C#, you never expect `x` to be changed. 
+0

No, en absoluto. ¿Solo hace que la sobrecarga del operador tome el parámetro ref? –

+0

Ivan: ¿cómo llamarías al operador sobrecargado? Si un método toma un parámetro 'ref', el sitio de llamada ** y ** el sitio de definición deben ** declarar ** explícitamente el parámetro como' ref'. –

+0

Mehrdad: Esto está perfectamente bien. Tienen una firma diferente, por lo que llamar sin ref nunca coincidirá con una sobrecarga de ref. ¿Qué es tan complicado acerca de eso, que el equipo de C# no lo implementó? ¿Qué ocurre si realmente necesito modificar un operando que no es un tipo de referencia? ¿Cómo lo hago? –

1

creo que se debe a un operador (en la vista más matemático que C# parece tomar) es Lógicamente, es algo que combina sus argumentos en un nuevo valor, que nunca se suponía que mutara nada. C++ parece considerar a los operadores más como una versión de operaciones generales con una sintaxis más conveniente que funciones, que como una forma de representar las matemáticas en particular. Creo que en C# casi nunca verás cosas como definir operadores para operaciones de flujo y tal.

Cuestiones relacionadas