C# 相当于 Python 的 id() 吗?

发布于 2024-10-07 04:27:26 字数 535 浏览 2 评论 0原文

是否有 C# 相当于 Python 的 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 作为答案。

Is there a C# equivalent to Python's id()? If not, how can I test if an object has changed? For example, in Python, an immutable object:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浮生未歇 2024-10-14 04:27:26

您可以使用 Object.ReferenceEquals

You can test object identity with Object.ReferenceEquals.

ま昔日黯然 2024-10-14 04:27:26

那么,您可以使用 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);

equal 将是 true

Well, you can use the Object.ReferenceEquals() function:

Determines whether the specified Object instances are the same instance.

To borrow your Python example a little bit:

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.

桃扇骨 2024-10-14 04:27:26

我认为你问错了问题。我的回答非常详细,但这里有一个快速总结:


首先,我将从 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 等效项.ReferenceEqualsid 仅保证在对象的生命周期内是常量。如上所示,id 对于不同的对象保证是不同的。特别是如果其中一个对象不再存在,由于重复使用相同的内存,您可以(有时会)获得相同的id。因此,使用 id 在这里是一个非常糟糕的主意。

总结

不要这样做。

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#.
  • You can get get the address of an object in C# using pointers, but you shouldn't use this to solve your problem.
  • The method object.ReferenceEquals does something similar to what you are trying to do.
  • The problem you are trying to solve doesn't really exist in C# in the same way is it does in Python.
  • The way you are using id doesn't solve the problem in Python either.

Firstly, I'll post from the documentation for id since most people don't seem to have read it. 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):

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.

CPython implementation detail: This is the address of the object.

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.

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

However you shouldn't do this in 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. 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. You should instead create a readonly property, called Id for example.


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. However you probably shouldn't do this either. C# doesn't have the same ambiguity as in 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; operator is (very nearly) equivalent to x = x + y and you can't change that like you can in Python.


Also, as mentioned in the documentation, your Python example is flawed - id cannot be used reliably to test if an object has changed. 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. id is only guaranteed to be the constant over the lifetime of an object. As shown above id is not guaranteed to be different for different objects. 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. As such the use of id is a really bad idea here.

Summary

Don't do it.

无风消散 2024-10-14 04:27:26

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

object.GetHashcode() might be worth a shot.

如若梦似彩虹 2024-10-14 04:27:26

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

对象.GetHashCode()

wes, the correct answer to your question, ie.. an analogous function to id() is

object.GetHashCode()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文