Is there a C# equivalent to Python's id()? If not, how can I test if an object has changed? For example, in Python, a开发者_运维问答n 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.
You can test object identity with Object.ReferenceEquals
.
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
.
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.
object.GetHashcode()
might be worth a shot.
wes, the correct answer to your question, ie.. an analogous function to id() is
object.GetHashCode()
精彩评论