简体   繁体   English

C#相当于Python的id()?

[英]C# equivalent of Python's id()?

Is there a C# equivalent to Python's id() ? 是否有一个C#等同于Python的id() If not, how can I test if an object has changed? 如果没有,我如何测试对象是否已更改? For example, in Python, an immutable object: 例如,在Python中,一个不可变对象:

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

and a mutable one: 一个可变的:

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

Edit - Most of the answers so far are about comparison functions/operators but I'm more interested in the values that are being compared. 编辑 - 到目前为止,大多数答案都是关于比较函数/运算符,但我对正在比较的值更感兴趣。 I wasn't initially clear about that, and I'm accepting Object.ReferenceEquals as the answer. 我最初并不清楚这一点,我接受Object.ReferenceEquals作为答案。

您可以使用Object.ReferenceEquals测试对象标识。

Well, you can use the Object.ReferenceEquals() function: 好吧,你可以使用Object.ReferenceEquals()函数:

Determines whether the specified Object instances are the same instance. 确定指定的Object实例是否是同一实例。

To borrow your Python example a little bit: 借用你的Python示例:

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

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

equal will be true . equal将是true

I think you're asking the wrong question. 我想你问的是错误的问题。 My answer is quite detailed, but here's a quick summary: 我的答案非常详细,但这里有一个简短的总结:

  • There is no direct equivalent to id in C#. 在C#中没有直接等同的id
  • You can get get the address of an object in C# using pointers, but you shouldn't use this to solve your problem. 您可以使用指针获取C#中对象的地址,但不应使用它来解决您的问题。
  • The method object.ReferenceEquals does something similar to what you are trying to do. 方法object.ReferenceEquals执行类似于您尝试执行的操作。
  • The problem you are trying to solve doesn't really exist in C# in the same way is it does in Python. 你试图解决的问题在C#中并不存在,就像它在Python中一样。
  • The way you are using id doesn't solve the problem in Python either. 你使用id的方式也没有解决Python中的问题。

Firstly, I'll post from the documentation for id since most people don't seem to have read it. 首先,我将从id文档发布,因为大多数人似乎没有阅读它。 Please do read this because the rest of my answer only makes sense if you know what id does (and no, it doesn't create a hash code): 务必阅读这一点,因为我的回答其余只有当你知道什么是有意义的id不(不,它不会创建一个散列码):

Return the “identity” of an object. 返回对象的“标识”。 This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. 这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。 Two objects with non-overlapping lifetimes may have the same id() value. 具有非重叠生存期的两个对象可以具有相同的id()值。

CPython implementation detail: This is the address of the object. CPython实现细节:这是对象的地址。

C# doesn't have an equivalent to id but it is possible to get the address of the object by getting a pointer to the object in unsafe mode. C#没有id的等价物,但可以通过在不安全模式下获取指向对象的指针来获取对象的地址。

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

However you shouldn't do this in C#. 但是你不应该在C#中这样做 You very rarely need to use unsafe code in C#, and if you do it can easily spread as code that calls your code also becomes unsafe. 您很少需要在C#中使用不安全的代码,如果这样做,很容易传播,因为调用代码的代码也变得不安全。 There are other ways to solve your problem that don't need unsafe code. 还有其他方法可以解决您的问题,不需要不安全的代码。 Besides, in .NET (unlike in Python) objects can be moved about in memory by the garbage collector, so if you want a single identity that remains constant for the entire lifetime of the object, the memory address is of no use to you. 此外,在.NET中(与Python不同)垃圾收集器可以在内存中移动对象,因此如果您希望单个标识在对象的整个生命周期内保持不变,则内存地址对您没用。 You should instead create a readonly property, called Id for example. 您应该创建一个只读属性,例如Id


An alternative approach which is possible in C# without using unsafe code is to test if two variables have the same reference using Object.ReferenceEquals . 在不使用不安全代码的情况下在C#中可能的替代方法是使用Object.ReferenceEquals测试两个变量是否具有相同的引用。 However you probably shouldn't do this either. 但是你也许不应该这样做。 C# doesn't have the same ambiguity as in Python. C#没有Python中那样的歧义。 To set a variable to point to a new object you use the = operator. 要将变量设置为指向新对象,请使用=运算符。 Calling a method almost always won't change the reference, so you shouldn't worry about it. 调用方法几乎总是不会改变引用,所以你不必担心它。 In C# x += y; 在C# x += y; operator is (very nearly) equivalent to x = x + y and you can't change that like you can in Python. operator(非常接近)等效于x = x + y ,你不能像在Python中那样改变它。


Also, as mentioned in the documentation, your Python example is flawed - id cannot be used reliably to test if an object has changed. 此外,如文档中所述,您的Python示例存在缺陷 - 无法可靠地使用id来测试对象是否已更改。 Example: 例:

>>> 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.

In Python if you have to compare two objects to see if they are the same object (and you probably shouldn't be doing this) then use is which is the Python equivalent of object.ReferenceEquals . 在Python中,如果你必须比较两个对象以查看它们是否是同一个对象(你可能不应该这样做),那么使用的isobject.ReferenceEquals相当的Python。 id is only guaranteed to be the constant over the lifetime of an object. id仅保证是对象生命周期内的常量。 As shown above id is not guaranteed to be different for different objects. 如上所示, 保证不同对象的id不同。 In particular if one of the objects no longer exists you can (and sometimes will) get the same id due to reuse of the same memory. 特别是如果其中一个对象不再存在,由于重用相同的内存,您可以(有时会)获得相同的id As such the use of id is a really bad idea here. 因此,在这里使用id是一个非常糟糕的主意。

Summary 摘要

Don't do it. 不要这样做。

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

wes, the correct answer to your question, ie.. an analogous function to id() is wes,你问题的正确答案,即......与id()的类似函数

object.GetHashCode() object.GetHashCode()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM