题
有等效于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()