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

Kur*_*isu 10 c# casting

我目前正在使用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); 
    }
Run Code Online (Sandbox Code Playgroud)

这段代码的目的是有一个按钮,它隐藏容器中的所有其他按钮,除了它本身,然后变成一个取消隐藏按钮,反向执行相同的操作.

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

但是很低,它看起来就像我想要的那样,并且最初认为它会.这让我想知道,演员是否总是返回对原始对象的引用?如果没有,我如何保证(按钮)发件人=发件人?

我知道双打/整体不是这样的

        public static int Main()
    {
        int a;
        double b;
        b = 10.5;
        a = (int)b;
        a++;
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 17

适用于参考类型.如果转换只是继承层次结构的上升或下降,那么是.这是参考转换.从C#3.0语言规范,第6.2.4节:

隐式或显式的引用转换永远不会更改要转换的对象的引用标识.换句话说,虽然引用转换可能会更改引用的类型,但它永远不会更改所引用对象的类型或值.

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

但是,在其他(仍然是引用类型)的情况下,它可以调用用户定义的转换.例如:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样的用户定义的转换是相对罕见的.

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


Meh*_*ari 12

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