4

是否有与 Python 的id()等效的 C# ?如果没有,我如何测试对象是否已更改?例如,在 Python 中,一个不可变对象:

>>> s = "abc"
>>> id(s)
11172320
>>> s += "d"
>>> id(s)
18632928

和一个可变的:

>>> a = [1, 2, 3]
>>> id(a)
11259656
>>> a += [4]
>>> id(a)
11259656

编辑 - 到目前为止,大多数答案都是关于比较函数/运算符,但我对正在比较的值更感兴趣。我最初并不清楚这一点,我接受Object.ReferenceEquals了这个答案。

4

5 回答 5

5

您可以使用 测试对象身份Object.ReferenceEquals

于 2010-12-09T15:36:40.817 回答
4

好吧,您可以使用以下Object.ReferenceEquals()功能:

确定指定的 Object 实例是否为同一个实例。

稍微借用一下您的 Python 示例:

List<int> listA = new List<int> { 1, 2, 3 };
List<int> listB = listA;
listA.Add(4);

bool equal = object.ReferenceEquals(listA, listB);

equaltrue

于 2010-12-09T15:36:27.370 回答
4

我想你问错问题了。我的回答非常详细,但这里有一个简短的总结:

  • id在 C#中没有直接的等价物。
  • 您可以使用指针在 C# 中获取对象的地址,但您不应该使用它来解决您的问题。
  • 该方法执行的object.ReferenceEquals操作与您尝试执行的操作类似。
  • 您尝试解决的问题在 C# 中并不像在 Python 中那样真正存在。
  • 您使用的方式也id不能解决 Python 中的问题。

首先,我将从id 的文档中发布,因为大多数人似乎没有阅读过它。请务必阅读此内容,因为我的其余答案只有在您知道做什么时才有意义id(不,它不会创建哈希码):

返回对象的“身份”。这是一个整数(或长整数),保证该对象在其生命周期内是唯一且恒定的。具有非重叠生命周期的两个对象可能具有相同的 id() 值。

CPython 实现细节:这是对象的地址。

C# 没有等价物,id但可以通过在不安全模式下获取指向对象的指针来获取对象的地址。

unsafe
{
     IntPtr x = (IntPtr)(&v);
     Console.WriteLine(x);
}

但是,您不应该在 C# 中执行此操作。你很少需要在 C# 中使用不安全的代码,如果你这样做,它很容易传播,因为调用你的代码的代码也会变得不安全。还有其他不需要不安全代码的方法来解决您的问题。此外,在 .NET(与 Python 中不同)中,垃圾收集器可以在内存中移动对象,因此如果您想要一个在对象的整个生命周期内保持不变的单一标识,那么内存地址对您没有用处。相反,您应该创建一个只读属性,Id例如调用。


在 C# 中不使用不安全代码的另一种方法是使用Object.ReferenceEquals. 但是,您可能也不应该这样做。C# 没有与 Python 相同的歧义。要将变量设置为指向新对象,请使用=运算符。调用方法几乎总是不会更改引用,因此您不必担心。在 C#x += y;中,运算符(非常接近)等同于x = x + y并且您不能像在 Python 中那样更改它。


此外,如文档中所述,您的 Python 示例存在缺陷 -id无法可靠地用于测试对象是否已更改。例子:

>>> s='abc'
>>> id(s)
37822208
>>> s+='d'
>>> id(s)
61711680    # Changes
>>> s+='e'
>>> id(s)
61711680    # Oops... doesn't change even though the value changed.

在 Python 中,如果您必须比较两个对象以查看它们是否是同一个对象(并且您可能不应该这样做),那么请使用isPython 中的object.ReferenceEquals. id只保证在对象的生命周期内是常量。如上所示,id保证对于不同的对象是不同的。特别是如果其中一个对象不再存在,id由于重用相同的内存,您可以(有时会)得到相同的对象。因此,在id这里使用 是一个非常糟糕的主意。

概括

不要这样做。

于 2010-12-09T15:36:55.317 回答
3

object.GetHashcode()可能值得一试。

于 2010-12-09T15:37:02.423 回答
0

wes,您问题的正确答案,即.. id() 的类似函数是

object.GetHashCode()

于 2010-12-09T17:52:46.407 回答