Сравнение ссылочного значения в C # так же, как C / C ++ - PullRequest
0 голосов
/ 09 февраля 2012

У меня есть класс B, который имеет класс A, это упрощенная версия классов A и 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;
    }
    ...
}

И мне нужно сравнить объект а следующим образом.

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

Значение a == b.getA() всегда было истинным, но после синхронизации с новыми A и B теперь a != b.getA(). Я сравнил элемент с элементом a и b.getA () с помощью отладчика, но они кажутся одинаковыми.

Есть ли способ сравнить ссылку (адрес) a и b.getA ()? С C / C ++ я мог бы легко получить значение указателя, но я не знаю, как я могу сделать это с C #.

Ответы [ 5 ]

2 голосов
/ 09 февраля 2012

Вы можете использовать для этого Object.ReferenceEquals .Если вы не переопределите Equals или ==, то получится тот же результат.

1 голос
/ 09 февраля 2012

Если вы не используете небезопасный код, вы не можете использовать указатели в C #. Это очень обдуманное решение разработчиков языка, так как указатели подвержены ошибкам и усложняют оптимизацию и сборку мусора. Тем не менее, вы можете сравнить два объекта по «адресу», т.е. проверить, что они являются одной и той же ссылкой, используя

Console.WriteLine(object.ReferenceEquals(a, b.getA()));
0 голосов
/ 09 февраля 2012

Вы можете либо использовать метод «Object.ReferenceEquals» для сравнения ссылочного типа в терминах C #, либо вы можете получить адрес ссылочного типа и затем сравнить, как в 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());
}

Вы можетеПодробнее о Blittable и Non-Blittable здесь .

надеюсь, что этот пост поможет !!

0 голосов
/ 09 февраля 2012

Как уже упоминалось, Object.ReferenceEquals будет делать то, что вы здесь.

Использование небезопасного кода также возможно и может быть полезно для определенных приложений.Для того, что вы показали здесь, это было бы честно излишне и, вероятно, не стоило бы возможностей ошибок и проблем с оптимизацией, на которые указывает Адам, - но вариант, безусловно, есть и, безусловно, стоит того, если скорость станет проблемой.Или если вы испытываете ностальгию по ошибкам, связанным с памятью!

Но, как упоминается в Руководстве по небезопасному коду , ... использование указателей в C # является редкостью.

0 голосов
/ 09 февраля 2012

Используйте Object.ReferenceEquals метод. Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...