有等效于python的c#吗 ID()?如果没有,如何测试对象是否已更改?例如,在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 作为答案。

有帮助吗?

解决方案

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

确定指定的对象实例是否为同一实例。

借用您的python示例:

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

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

equal 将会 true.

其他提示

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

我认为您问了错误的问题。我的答案非常详细,但这是一个快速的摘要:

  • 没有直接等效的 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中,如果您必须比较两个对象才能查看它们是否是同一对象(并且您可能不应该这样做)然后使用 is 这是python等效的 object.ReferenceEquals. id 仅保证在对象的整个生命周期内是恒定的。如上所示 id不是 保证在不同对象的不同对象中会有所不同。特别是如果其中一个对象不再存在,您可以(有时)获得相同的 id 由于重复使用相同的内存。因此使用 id 这里是一个非常糟糕的主意。

概括

不要做。

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

wes,您问题的正确答案,即。

object.gethashcode()

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top