If I cast an object in C#, does it still reference the original object cast?
As an example, if I create a method to change an object and then cast that object depending on specific implementation called, does the original object get preserved?
public bool CallChangeString()
{
String str = "hello";
ChangeObject(str);
return String.Equals("HELLO", str);
}
public void ChangeObject(Object obj)
{
String str = obj as String;
str.ToUpper(); // pretend for the sake of this that this changes str to upper case
}
In this case, would the String.Equals return true or false?
Are there any situations where casting would cause the new object to not preserve it's reference?
Depends on what cast you are doing. You can think of two main groups of casting:
Well, thats not very helpful, that is precisely what you are asking.
What casts don't preserve identity? All those that entail a representational change in the object itself, that is, the bits that make up the object change.
Examples? All casts between value types: int
to long
, int
to double
, etc., any boxing or unboxing conversion, etc. The bits that make up a long
are very different from those that make up an int
.
More examples? Any user defined cast operator, explicit or implicit. Why? Because user defined casts that preserve identity are disallowed by the compiler simply because the compiler already does them for you:
class Foo : IFoo
{
public static implicit operator object(Foo foo) => return foo; //Compile time error
public static implicit operator IFoo(Foo foo) => return foo; //compile time error.
public static explicit operator Bar(Foo foo) => return new Bar(foo);
}
Note the general pattern of user defined casts:
new
lurking
around in whatever it returns. Thats telling you right away that the
cast can not preserve identity... you are returning a new object.So, what are identity preserving casts or conversions? Well, those that don't touch the object all; reference conversions.
Huh? But wait, The whole point is that I'm casting the object, how can that be?
In reference conversions you are only "casting" the reference pointing to the object. The object is always the same. This, of course, only makes sense in reference types and that is why value types don't have identity preserving conversions; there are no references to value types unless they are boxed.
Examples? object
to string
, Foo
to IFoo
, Giraffe
to Animal
, etc.
Do note that reference types can very well implement user defined casts too, but these will not preserve identity.
All that said, this is the rule of the thumb:
(long)2
is a user defined cast, somebody had to implement it in the class System.Int64
).So, answering your question, var str = obj as string
is a reference conversion, which means that ReferenceEquals(str, obj)
is true
; str
and obj
point to exactly the same object, the only difference is the type of the reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With