prosseek
prosseek

Reputation: 190709

Comparing the reference value in C# just like C/C++

I have class B that has class A, this is simplified version of class A and B.

class A
{
    int x;
    int y;

    public A(int x, int y)
    {
        this.x = x;
        this.y = y;
    }   

    public A()
    {
        x = 0;
        y = 0;
    }
    ...
}

class B
{
    A a;
    public B(A a)
    {
        this.a = a;
    }

    public B()
    {
        this.a = null;
    }

    public A getA()
    {
        return a;
    }
    ...
}

And I need to compare the object a as follows.

public class MyClass
{
    public static void RunSnippet()
    {
        var a = new A(10, 20);
        var b = new B(a);
        Console.WriteLine(a == b.getA());
    }
}

The a == b.getA() was always true, but after syncing to the new A and B, now a != b.getA(). I compared the element by element of a, and b.getA() using debugger, but they seem to be the same.

Is there any way to compare the reference (the address) of a and b.getA()? With C/C++, I could easily get the pointer value, but I don't know how can I do that with C#.

Upvotes: 0

Views: 3443

Answers (5)

Rahul20
Rahul20

Reputation: 26

You can either use "Object.ReferenceEquals" method for comparing the reference type in terms of C# or you can get the address of the reference type and then compare as in C++.

[StructLayout(LayoutKind.Sequential)] // To make type [Class A] blittable
Class A
{
    int x;    

    public A(int x)
    {
        this.x = x;
    }   
    ...
}

Class B
{
    A a;
    public B(A a)
    {
        this.a = a;
    }    

    public A GetA()
    {
        return a;
    }
    ...
}

main()
{
    var a = new A(10, 20);
    var b = new B(a);
    GCHandle gc = GCHandle.Alloc(objA, GCHandleType.Pinned); // Through GCHandle you can access the managed object from unmanaged memory.
    IntPtr add = gc.AddrOfPinnedObject();  //pointer
    Console.WriteLine(add.ToString());
}

You can read more about blittable and non-blittable here.

hope this post helps !!

Upvotes: 0

Ancallan
Ancallan

Reputation: 111

As mentioned, Object.ReferenceEquals will do what you're after here.

Using unsafe code is also a possibility and could be useful for certain applications. For what you've shown here, it would quite honestly be overkill and likely not worth the possibilities of errors and optimization troubles that Adam points out - but the option is certainly there and is definitely worthwhile if speed becomes an issue. Or if you're feeling nostalgic for memory-related errors!

But, as the Unsafe Code Tutorial mentions... the use of pointers in C# is a rarity.

Upvotes: 0

Adam Mihalcin
Adam Mihalcin

Reputation: 14458

Unless you are using unsafe code, you cannot use pointers in C#. This is a very deliberate decision by the language designers, since pointers are error-prone and make optimization and garbage collection harder. However, you can compare two objects by "address" i.e. check that they are the same reference, by using

Console.WriteLine(object.ReferenceEquals(a, b.getA()));

Upvotes: 1

Krzysztof Kozielczyk
Krzysztof Kozielczyk

Reputation: 5937

Use Object.ReferenceEquals method. Good luck.

Upvotes: 0

cadrell0
cadrell0

Reputation: 17307

You can use Object.ReferenceEquals for this. If you don't override Equals or == it will produce the same result.

ex ReferenceEquals(a, b.getA()

Upvotes: 2

Related Questions