【问题标题】:Comparing the reference value in C# just like C/C++像 C/C++ 一样比较 C# 中的参考值
【发布时间】:2012-02-09 03:24:27
【问题描述】:

我有 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;
    }
    ...
}

我需要比较对象 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# 来做到这一点。

【问题讨论】:

  • 是我没抓住重点,还是您在寻找Object.ReferenceEquals
  • 由于 A 和 B 是引用类型,而不是值类型,因此比较“它们的指针”正是您已经在做的事情;这就是为什么它返回平等。
  • 除非你正在使用奇怪的类,否则 == 会为类做你想要的(不是值类型/字符串)。如果有人覆盖 == 运算符,请小心。 Object.ReferenceEquals 是最安全的(但不那么漂亮)。

标签: c# debugging pointers reference


【解决方案1】:

您可以为此使用Object.ReferenceEquals。如果您不覆盖 Equals==,它将产生相同的结果。

ReferenceEquals(a, b.getA()

【讨论】:

    【解决方案2】:

    除非您使用不安全的代码,否则您不能在 C# 中使用指针。这是语言设计者深思熟虑的决定,因为指针容易出错并使优化和垃圾收集更加困难。但是,您可以通过“地址”比较两个对象,即检查它们是否是相同的引用,使用

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

    【讨论】:

      【解决方案3】:

      使用Object.ReferenceEquals 方法。祝你好运。

      【讨论】:

        【解决方案4】:

        如前所述,Object.ReferenceEquals 将在这里做你想做的事。

        使用unsafe 代码也是一种可能性,并且可能对某些应用程序有用。对于您在此处显示的内容,老实说,这将是矫枉过正,并且可能不值得亚当指出的错误和优化问题的可能性-但是该选项肯定存在,如果速度成为问题,绝对值得。或者,如果您对记忆相关的错误感到怀念!

        但是,正如 Unsafe Code Tutorial 所提到的......在 C# 中使用指针是罕见的。

        【讨论】:

          【解决方案5】:

          您可以使用“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 和不可 blittable 的更多信息 here

          希望这篇文章有帮助!!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多