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

Object copy disappearing while using the using statement

我正在尝试了解 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 语句创建一个 TextBoxmyeventtxtbox),它与 mytextbox(属性 等)完全相同,但不是 mytextbox。 那么为什么 mytextbox 在退出 using 语句时被释放?只应发布 myeventtxtbox(副本)。

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

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

Reference Types are used by a reference which holds a reference (address) to the object but not the object itself. Because reference types represent the address of the variable rather than the data itself, assigning a reference variable to another doesn't copy the data. Instead it creates a second copy of the reference, which refers to the same location of the heap as the original value. Reference Type variables are stored in a different area of memory called the heap. This means that when a reference type variable is no longer used, it can be marked for garbage collection.

以下帖子也可能很有趣:

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

Shallow copy or Deep copy?

我认为问题在于您假设:

TextBox myeventtxtbox = (TextBox)sender

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

重要的是要认识到,无论您引用了多少个不同的变量,它仍然只有一个文本框。如果您喜欢打个比方,如果文本框是一台电视,则建立另一个变量引用就像购买另一个遥控器一样。你现在有 3 个遥控器,其中任何一个都可以关闭电视。如果遥控器是某种显示电视状态的智能类型的东西,那么所有 3 个遥控器都会在其中任何一个关闭电视后报告电视已关闭(处置)。使用遥控器 1 关闭电视后无法使用遥控器 2 调高音量

回到c#

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

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

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

要理解这个问题,首先要理解C#中的对象(引用类型)是如何传递的。

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

所以你的两个文本框变量都指向你记忆中的同一个对象。

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

这里mytextboxmyeventtxtbox指向同一个对象,因为它们是引用类型。

您需要的是克隆控件。我想这个 link 会对你有所帮助 :

Clone a control

克隆时,实际上是将旧控件的所有属性复制到新控件中。

This 已经准备了一个漂亮的扩展方法,你可以将其用于所有控件,包括 TextBox