Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

306
Visualizações
Reference equality of value types

I have made some ref keyword tests and there is one thing I can't understand:

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();
}

Why does this code display False? I know that int is a value type but here it should pass references to the same object.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Why does this code display False?

Because int a and int b are being boxed when you call object.ReferenceEquals. Each integer is boxed inside an object instance. Thus, you are actually comparing references between two boxed values, which clearly aren't equal.

You can easily see this if you look at the generated CIL for the method:

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

Checking for storage location equality can be achieved either by using verifiable CIL (such as in @leppie's answer) or by unsafe code:

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 4 years ago · Santiago Trujillo Relatório

0

This cannot be done directly in C#.

You can however implement it in verifiable CIL:

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

Tests

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

Notes

This does not actually check for the same reference, but even more fine-grained in that it makes sure both are the same 'location' (or referenced from the same variable) too. This is while the 3rd line returns false even though o == p returns true. The usefulness of this 'location' test is very limited though.

over 4 years ago · Santiago Trujillo Relatório

0

I know, that int is a value type but here it should pass references to the same object.

Yes, the reference passed to the method are the same, but they are boxed (converted to object/reference type) in the ReferenceEquals method.

That is why the result of your test returns false, since you are comparing references of two different objects, due to boxing.

See: Object.ReferenceEquals Method

When comparing value types. If objA and objB are value types, they are boxed before they are passed to the ReferenceEquals method. This means that if both objA and objB represent the same instance of a value type, the ReferenceEquals method nevertheless returns false

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda