I'm currently doing a project in C# working with windows forms. During the course of it, I did the following
void HideButtons(object sender, EventArgs e)
{
Button hider = ((Button)sender);
foreach(Button tohide in hider.Parent.Controls)
tohide.Hide();
hider.Show();
hider.Text = "UnHide";
hider.Click -= new EventHandler(HideButtons);
hider.Click += new EventHandler(ShowButtons);
}
The purpose of this code is to have a button which hides all the other buttons in the container it's in except itself, and then turn into an Unhide button which does the same thing in reverse.
Now, that's all well and good, except, as I compile this, I realize to myself I've hit a problem. hider is its unique object, being the return from ((Button)sender). It's not necessarily the reference to sender, and this code will probably do nothing.
But low and behold, it works exactly like I wanted it to and initially thought it would. Which got me to wondering, does a cast always return a reference to the original object? If not, how do I guarantee that (button)sender = sender?
I know that's not the case for doubles/ints, as
public static int Main()
{
int a;
double b;
b = 10.5;
a = (int)b;
a++;
return 0;
}
ends up with a being 11, and b being 10.5 But that may be due to doubles/ints being structs. This behavior worries me, and it'd be nice to know that it will always return a reference so I can put my worrysome mind to rest.
For reference types. if the cast is just up or down the inheritance hierarchy, then yes. This is a reference conversion. From the C# 3.0 language spec, section 6.2.4:
Reference conversions, implicit or explicit, never change the referential identity of the object being converted. In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.
This is the case you're using in your WinForms code.
However, in other (still reference type) cases it may invoke a user-defined conversion. For example:
using System;
class Foo
{
}
class Bar
{
public static explicit operator Bar(Foo f)
{
return new Bar();
}
}
class Test
{
static void Main()
{
Foo f = new Foo();
Bar b = (Bar) f;
Console.WriteLine(object.ReferenceEquals(f, b)); // Prints False
}
}
User-defined conversions like this are relatively rare.
For value types, there are boxing and unboxing conversions, along with other conversions (e.g. between int
and double
).
For reference types casted through the inheritance hierarchy, it'll always reference the same instance. However, for value types, casts might involve boxing and unboxing which will copy stuff. Other than that, casts are not just in the inheritance hierarchy. You can declare your own cast operator which has the characteristics of a method. It can return whatever object it likes.
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