• Jobs
  • About Us
  • Jobs
    • Home
    • Jobs
    • Courses and challenges
  • Businesses
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

249
Views
Igualdad de referencia de tipos de valor

Hice algunas pruebas de palabras clave ref y hay una cosa que no puedo entender:

 static void Test(ref int a, ref int b) { Console.WriteLine(Int32.ReferenceEquals(a,b)); } static void Main(string[] args) { int a = 4; Test(ref a, ref a); Console.ReadLine(); }

¿Por qué este código muestra False ? Sé que int es un tipo de valor, pero aquí debería pasar referencias al mismo objeto.

over 3 years ago · Santiago Trujillo
3 answers
Answer question

0

¿Por qué este código muestra False ?

Porque int a e int b están encuadrados cuando llamas a object.ReferenceEquals . Cada entero está encuadrado dentro de una instancia de object . Por lo tanto, en realidad está comparando referencias entre dos valores encuadrados, que claramente no son iguales.

Puede ver esto fácilmente si observa el CIL generado para el método:

 Test: IL_0000: nop IL_0001: ldarg.0 Load argument a IL_0002: ldind.i4 IL_0003: box System.Int32 IL_0008: ldarg.1 Load argument b IL_0009: ldind.i4 IL_000A: box System.Int32 IL_000F: call System.Object.ReferenceEquals IL_0014: call System.Console.WriteLine IL_0019: nop IL_001A: ret

La verificación de la igualdad de ubicación de almacenamiento se puede lograr mediante el uso de CIL verificable (como en la respuesta de @leppie ) o mediante un código unsafe :

 unsafe static void Main(string[] args) { int a = 4; int b = 5; Console.WriteLine(Test(ref a, ref a)); // True Console.WriteLine(Test(ref a, ref b)); // False; } unsafe static bool Test(ref int a, ref int b) { fixed (int* refA = &a) fixed (int* refB = &b) { return refA == refB; } }
over 3 years ago · Santiago Trujillo Report

0

Esto no se puede hacer directamente en C#.

Sin embargo, puede implementarlo en CIL verificable:

 .method public hidebysig static bool Test<T>(!!T& a, !!T& b) cil managed { .maxstack 8 ldarg.0 ldarg.1 ceq ret }

Pruebas

 int a = 4, b = 4, c = 5; int* aa = &a; // unsafe needed for this object o = a, p = o; Console.WriteLine(Test(ref a, ref a)); // True Console.WriteLine(Test(ref o, ref o)); // True Console.WriteLine(Test(ref o, ref p)); // False Console.WriteLine(Test(ref a, ref b)); // False Console.WriteLine(Test(ref a, ref c)); // False Console.WriteLine(Test(ref a, ref *aa)); // True // all of the above works for fields, parameters and locals

notas

En realidad, esto no verifica la misma referencia, pero es aún más detallado en el sentido de que se asegura de que ambos estén en la misma 'ubicación' (o referenciados desde la misma variable) también. Esto es mientras que la tercera línea devuelve false aunque o == p devuelve true . Sin embargo, la utilidad de esta prueba de 'ubicación' es muy limitada.

over 3 years ago · Santiago Trujillo Report

0

Lo sé, ese int es un tipo de valor, pero aquí debería pasar referencias al mismo objeto.

Sí, la referencia pasada al método es la misma, pero están encuadradas (convertidas a tipo de objeto/referencia) en el método ReferenceEquals .

Es por eso que el resultado de su prueba devuelve falso, ya que está comparando referencias de dos objetos diferentes, debido al boxeo .

Ver: Método Object.ReferenceEquals

Al comparar tipos de valores. Si objA y objB son tipos de valor, se encuadran antes de pasar al método ReferenceEquals . Esto significa que si tanto objA como objB representan la misma instancia de un tipo de valor, el método ReferenceEquals devuelve falso.

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Show me some job opportunities
There's an error!