Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

You can test object identity with Object.ReferenceEquals.

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()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top