使用using语句时对象副本消失

时间:2018-12-17 06:47:47

标签: c# object events using

我试图了解using语句的工作方式,因为我在文本框(mytextbox)下面运行的代码消失了。

public partial class Form1 : Form
{
    TextBox mytextbox = new TextBox();
    public Form1()
    {
        InitializeComponent();
        this.Controls.Add(mytextbox);
        mytextbox.Validated+=new EventHandler(mytextbox_Validated);
    }
    private void mytextbox_Validated(object sender, EventArgs etxtbox)
    {
        using (TextBox myeventtxtbox = ((TextBox)sender))
        { 

        }
    }
}

我本以为using语句将在语句末尾释放myeventtxtbox,但也不会释放mytxtbox

我在这段代码中的工作: 我创建了一个object mytxtbox,它将保留在主窗体(Form1)上。 我还创建了一个事件,该事件将在经过验证的mytxtbox上引发。 如果我正在使用using语句创建一个TextBox(属性等)完全相同的myeventtxtboxmytextbox),但不是mytextbox 。 为什么mytextbox在退出using语句时被释放?只能发布myeventtxtbox(副本)。

我真的很想念这里的东西,你能帮我吗?

4 个答案:

答案 0 :(得分:3)

它们是引用类型。因此,myeventtxtbox不会复制任何内容。 mytextboxmyeventtxtbox都指向同一对象,它们之间的唯一区别是引用的名称。基于this

  

引用类型由保存引用的引用使用   (地址)到对象,而不是对象本身。因为参考   类型代表变量的地址而不是数据   本身,将引用变量分配给另一个变量不会复制   数据。相反,它创建引用的第二个副本,该副本引用   到堆中与原始值相同的位置。参考类型   变量存储在另一个称为堆的内存区域中。   这意味着当不再使用引用类型变量时,它将   可以标记为垃圾回收。

以下帖子也可能很有趣:

What is the difference between a reference type and value type in c#?

Shallow copy or Deep copy?

答案 1 :(得分:3)

我认为问题在于您假设这样做:

TextBox myeventtxtbox = (TextBox)sender

正在复制文本框,因此您将以某种方式在内存中拥有两个文本框。并非如此,它只是创建了另一个引用同一文本框的变量。 sender也是对表单上文本框的变量引用,您的textbox在using语句中也因此具有3个不同的变量,都指向同一个文本框

非常重要的一点是,不管您引用了多少个不同的变量,仍然只有一个文本框。如果您喜欢一个类比,如果文本框是电视,则建立另一个变量引用就像购买另一个遥控器一样。您现在拥有3个遥控器,其中任何一个都可以关闭电视。如果遥控器是显示电视状态的某种智能型物品,则所有3个遥控器在任何一个关闭后都会报告电视已关闭(配置)。使用遥控器1关闭电视后,无法使用遥控器2调高音量。

返回c#

最终,在对文本框的任何变量引用上调用.Dispose()时,将放置文本框本身,而不是对其的引用。 using语句的想法是,它放置在圆括号中设置的对象实例。在您的任何名称上调用dispose对文本框的变量引用(mytextbox,myeventtextbox,sender都是对它的引用)将对文本框本身进行处置,因此当using语句结束并调用myeventtextbox.Dispose()时,所有其他变量引用都会现在与已处置的文本框相关联

我们不需要像其他语言那样需要在c#中微管理变量。变量引用超出范围时会清除(当执行离开声明该变量的大括号块时)。当不再存在对内存中对象的引用时,该对象将从内存中删除

在这种情况下,事件处理程序完成执行时,sendermyeventtextbox将不再存在作为对文本框的引用。该文本框将仍然存在,因为mytextbox仍然引用它。表单的.Controls集合也引用了它。如果您从.Controls中删除了该控件,并且mytextbox被设置为null,那么该文本框将不再存在引用,并且将从内存中删除

答案 2 :(得分:1)

要了解此问题,您首先必须了解如何传递C#中的对象(引用类型)。

顾名思义,当您传递引用类型时,您“复制”的唯一信息就是其引用(基本上是RAM中的内存地址)。

因此,您的两个文本框变量都指向内存中的同一对象。

因此,在using语句结束时,将释放GUI中的文本框。

答案 3 :(得分:1)

此处mytextboxmyeventtxtbox指向同一对象,因为它们是引用类型。

您需要的是克隆控件。我想这个链接会为您提供帮助:

Clone a control

在克隆期间,您实际上将所有旧控件的道具复制到了新控件中。

This准备了漂亮的扩展方法,您可以将其用于包括TextBox在内的所有控件