2012-07-16 5 views
10

En C# Dada una función con el siguiente firmaCómo probar si los argumentos C# ref hacer referencia al mismo artículo

public static void Foo(ref int x, ref int y) 

Si la función se llama usando

int A = 10; 
Foo(ref A, ref A) 

Dentro de la función Foo es posible para probar que los argumentos xey hacen referencia a la misma variable? Una prueba equivalente simple de xey no es suficiente ya que esto también es cierto en el caso de que dos variables diferentes tengan el mismo valor.

+3

¿Cuál es su problema subyacente? Si el alias está causando problemas, simplemente opere las copias y actualice los parámetros como paso final. Las copias no serán alias. –

Respuesta

5

Si usted está dispuesto a utilizar código no seguro, se puede comparar el direcciones de variables subyacentes:

public static bool Foo(ref int a, ref int b) 
{ 
    unsafe 
    { 
     fixed (int* pa = &a, pb = &b) 
     { 
      // return true iff a and b are references to the same variable 
      return pa == pb; 
     } 
    } 
} 

(Modificado para eliminar unsafe de la firma del método, basado en el comentario de @Michael Graczyk.)

+2

IMO esta es la forma correcta de hacerlo a menos que * absolutamente * no pueda compilar con '/ inseguro'. Además, drf 'Foo' no necesita ser inseguro porque ni su valor de retorno ni ninguno de sus formales son tipos inseguros. –

+0

Puede colocar el bloque 'fixed' dentro de un bloque' inseguro'. –

+1

@Michael Graczyk Actualicé la respuesta por lo que el método no está declarado como inseguro. Gracias por la sugerencia. – drf

4

Puede usar Object.ReferenceEquals(x, y) para determinar si x y y fueron referencias al mismo objeto.

Editar: Como fue señalado por Kirk Woll (confirmado en este artículo en MSDN), este método no funciona para tipos de valores (debido al boxeo). Puede solucionar esto cambiando los tipos de parámetros en el método de int a object (por supuesto, esto significa que también tendrá que pasar una variable object al método, aunque todavía puede ser int).

es decir, el método se convierte en:

public static void Foo(ref object x, ref object y) { 
    Console.WriteLine("x and y the same ref: {0}", Object.ReferenceEquals(x, y)); 
} 

y llamándolo con:

object A = 10; 
Foo(ref A, ref A); 

dará lugar a "x and y are the same ref: True"

+3

Esto devolverá falso incluso si están haciendo referencia a la misma variable. (la igualdad de referencia no tiene sentido para las entradas y otras primitivas) –

+2

De MSDN: "Object.ReferenceEquals siempre devuelve falso para los tipos de valor" http://msdn.microsoft.com/en-us/library/dd183759.aspx – FishBasketGordo

+0

Esto dará como resultado false positivos. Considere: 'object a = new object(); objeto b = a; Foo (ref a, ref b); 'Esto afirma que xey son el mismo ref, pero no lo son. –

Cuestiones relacionadas