2010-04-15 17 views
5

¿Hay alguna manera de forzar a esta palabra clave a actuar como un argumento de referencia? Me gustaría pasar un visitante que modifica múltiples propiedades en el objeto, pero esto solo quiere actuar como un parámetro de valor.Usando un parámetro ref con la palabra clave this?

Código de objeto:

public void Accept(Visitor<MyObject> visitor) 
{ 
    visitor.Visit(this); 
} 

Código de Visitante:

public void Visit(ref Visitor<MyObject> receiver) 
{ 
    receiver.Property = new PropertyValue(); 
    receiver.Property2 = new PropertyValue(); 
} 

Respuesta

10

Ya que no está realmente cambiando lo que se refiere a receiver no hay necesidad de que la palabra clave ref. Sin embargo, si ese hubiera sido el caso, no podría hacer que this se refiera a otra instancia.

el fin de pasar this como parámetro ref, que tendría que escribir así:

Visit(ref this); 

Ese código no se compilará: "no puede pasar '<este>' como una referencia o fuera argumento porque es de solo lectura "

+0

Sí, tienes razón. Pero quiero que la clase original retenga los cambios realizados por el visitante. Si no paso como ref, ¿no solo modificaré las propiedades de una * copia * de ? – grefly

+0

@grefly: No si "esto" es una clase. Siempre que no "visite" una estructura personalizada (tipos de valor), no se requiere una referencia. –

+0

¡Gracias, tienes razón! – grefly

5

Si su Visitor<T> es una clase, entonces no necesita la palabra clave ref.

Toda la información dentro de una clase se cambia de forma automática si se cambian en un método

+0

Esto es correcto: lamento no poder marcar ambos como Respuestas. – grefly

0

lo que realmente necesita la palabra clave ref?

ref sería útil si cambia la instancia del receptor p. receptor = nulo;

lo contrario

receiver.Property es accesible también sin la palabra clave ref

4

Suena como que tienes una respuesta a su pregunta más amplia ya. Pero consideremos esto de todos modos.

¿Hay alguna manera de forzar a esta palabra clave a actuar como argumento de referencia?

Sí. Trabaja lógicamente.

  • Un argumento ref hace una alias para una variable .
  • "este" no es una variable en un tipo de referencia
  • "este" es una variable en un tipo de valor
  • , por tanto, la única manera de pasar un "ref este" es de un método de instancia de un tipo de valor .

Y de hecho, así es como "esto" se implementa en un tipo de valor detrás de las escenas. Cuando tienes una (¡peor práctica!en realidad no hacer esto) mutable tipo de valor:

struct S 
{ 
    private int x; 
    public void M() 
    { 
     this.x = 123; 
    } 
} 
... 
S s = new S(); 
s.M(); 

Desde las instancias de S se pasan por valor cómo es que muta M s? s debe pasar por referencia! De hecho, el código que generamos es como si usted había escrito algo así como:

struct S 
{ 
    private int x; 
    public static void M(ref S THIS) 
    { 
     THIS.x = 123; 
    } 
} 
... 
S s = new S(); 
S.M(ref s); 

En resumen, un "presente" en una estructura que ya se pasa como un parámetro de referencia, por lo que no hay ningún problema que pasa a lo largo de nuevo. Hacerlo es casi siempre una idea terrible pero es legal.

Cuestiones relacionadas