dotnet / docs

This repository contains .NET Documentation.
https://learn.microsoft.com/dotnet
Creative Commons Attribution 4.0 International
4.21k stars 5.86k forks source link

ReferenceEquals always returns false for struct comparison #41839

Open marchewek opened 1 month ago

marchewek commented 1 month ago

Type of issue

Other (describe below)

Description

The article attributes the fact that ReferenceEquals=false to the fact that a structure was copied, however it's not true - it will always return false, even in both examples (in which clearly no copy is involved); so it shouldn't be attributed to the fact of copying, but rather due to boxing ;)

public struct A
{
}

public class Assertions
{
    internal static A A1 = new A();

    public void Y()
    {
        Console.WriteLine(object.ReferenceEquals(A1, A1));
        Lol(ref A1);
    }

    private void Lol(ref A a)
    {
        Console.WriteLine(object.ReferenceEquals(A1, a));
    }
}

Page URL

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-test-for-reference-equality-identity

Content source URL

https://github.com/dotnet/docs/blob/main/docs/csharp/programming-guide/statements-expressions-operators/how-to-test-for-reference-equality-identity.md

Document Version Independent Id

b8e7e74e-d529-2397-a121-2cb7618a6cac

Article author

@BillWagner

Metadata

BillWagner commented 1 month ago

Hi @marchewek

I'll put this in the backlog so that we clarify the language. You're correct, but so is the current text. A boxing conversion does copy the struct (§10.2.9).

Boxing a value of a non-nullable-value-type consists of allocating an object instance and copying the value into that instance.

Yes, boxing conversions are involved. Yes, the struct is copied.

marchewek commented 1 month ago

Yes, I know that structures are copied; it's just that ReferenceEquals returns false for a completely different reason; it would also return false for a single structure used as its parameters twice:

var x = new MyStruct();
object.ReferenceEquals(x, x); // returns false as well

so beginners might be misled by the current statement: the "the structures are copied therefore ReferenceEquals returns false" implies that "well, so if they weren't copied, it would return true, right?"; nope, it wouldn't, because the parameters are boxed and two different objects are being reference-equal-ed.

If the example's aim is to prove that these are separate copies, then maybe after the copying, the first variable could be changed and the example could show that the second variable remains unchanged.