我试图了解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
(属性等)完全相同的myeventtxtbox
(mytextbox
),但不是mytextbox
。
为什么mytextbox
在退出using语句时被释放?只能发布myeventtxtbox
(副本)。
我真的很想念这里的东西,你能帮我吗?
答案 0 :(得分:3)
它们是引用类型。因此,myeventtxtbox
不会复制任何内容。 mytextbox
和myeventtxtbox
都指向同一对象,它们之间的唯一区别是引用的名称。基于this:
引用类型由保存引用的引用使用 (地址)到对象,而不是对象本身。因为参考 类型代表变量的地址而不是数据 本身,将引用变量分配给另一个变量不会复制 数据。相反,它创建引用的第二个副本,该副本引用 到堆中与原始值相同的位置。参考类型 变量存储在另一个称为堆的内存区域中。 这意味着当不再使用引用类型变量时,它将 可以标记为垃圾回收。
以下帖子也可能很有趣:
What is the difference between a reference type and value type in c#?
答案 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#中微管理变量。变量引用超出范围时会清除(当执行离开声明该变量的大括号块时)。当不再存在对内存中对象的引用时,该对象将从内存中删除
在这种情况下,事件处理程序完成执行时,sender
和myeventtextbox
将不再存在作为对文本框的引用。该文本框将仍然存在,因为mytextbox
仍然引用它。表单的.Controls
集合也引用了它。如果您从.Controls
中删除了该控件,并且mytextbox
被设置为null,那么该文本框将不再存在引用,并且将从内存中删除
答案 2 :(得分:1)
要了解此问题,您首先必须了解如何传递C#中的对象(引用类型)。
顾名思义,当您传递引用类型时,您“复制”的唯一信息就是其引用(基本上是RAM中的内存地址)。
因此,您的两个文本框变量都指向内存中的同一对象。
因此,在using语句结束时,将释放GUI中的文本框。
答案 3 :(得分:1)
此处mytextbox
和myeventtxtbox
指向同一对象,因为它们是引用类型。
您需要的是克隆控件。我想这个链接会为您提供帮助:
在克隆期间,您实际上将所有旧控件的道具复制到了新控件中。
This准备了漂亮的扩展方法,您可以将其用于包括TextBox在内的所有控件