在C#中转换Object总是返回对初始对象的引用

时间:2022-07-10 17:00:05

I'm currently doing a project in C# working with windows forms. During the course of it, I did the following

我目前正在使用Windows窗体进行C#项目。在此过程中,我做了以下几点

        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.

现在,这一切都很好,除了,当我编译这个时,我意识到我遇到了一个问题。 hider是它的唯一对象,是((Button)发送者的返回)。它不一定是发送者的引用,这段代码可能什么都不做。

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.

最终得到11,而b为10.5但这可能是由于双打/整数是结构。这种行为让我感到担忧,并且知道它总会返回一个引用会很好,所以我可以把我的烦恼放在心里休息。

2 个解决方案

#1


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:

适用于参考类型。如果转换只是继承层次结构的上升或下降,那么是。这是参考转换。从C#3.0语言规范,第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.

这是您在WinForms代码中使用的情况。

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

对于值类型,有装箱和拆箱转换以及其他转换(例如int和double之间)。

#2


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.

对于通过继承层次结构传递的引用类型,它将始终引用同一实例。但是,对于值类型,强制转换可能涉及装箱和拆箱,这将复制东西。除此之外,强制转换不仅仅在继承层次结构中。您可以声明自己的具有方法特征的强制转换运算符。它可以返回它喜欢的任何对象。

#1


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:

适用于参考类型。如果转换只是继承层次结构的上升或下降,那么是。这是参考转换。从C#3.0语言规范,第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.

这是您在WinForms代码中使用的情况。

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

对于值类型,有装箱和拆箱转换以及其他转换(例如int和double之间)。

#2


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.

对于通过继承层次结构传递的引用类型,它将始终引用同一实例。但是,对于值类型,强制转换可能涉及装箱和拆箱,这将复制东西。除此之外,强制转换不仅仅在继承层次结构中。您可以声明自己的具有方法特征的强制转换运算符。它可以返回它喜欢的任何对象。