Я пытаюсь понять, как работает оператор 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
(копия).
Мне здесь очень не хватает чего-то, не могли бы вы мне помочь?
Это ссылочные типы. Итак, myeventtxtbox
ничего не копирует. И mytextbox
, и myeventtxtbox
указывают на один и тот же объект, и единственное различие между ними - это имя ссылки. На основе это:
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.
Также могут быть интересны следующие сообщения:
Я думаю, проблема в том, что вы предполагаете следующее:
TextBox myeventtxtbox = (TextBox)sender
Создает копию вашего текстового поля, так что у вас как-то есть два текстовых поля в памяти. Это не так, он просто создает другую ссылку на переменную в том же текстовом поле. sender
также является переменной ссылкой на текстовое поле в форме, как и ваш textbox
. Таким образом, внутри оператора using у вас есть 3 разные переменные, все указывающие на одно и то же текстовое поле.
Важно понимать, что независимо от того, сколько разных переменных вы ссылаетесь на него, все равно остается только одно текстовое поле. Если вы оцените аналогию, если бы текстовое поле было телевизором, установка ссылки на другую переменную сродни покупке другого пульта ДУ. Теперь у вас есть 3 пульта ДУ, и любой из них может выключить телевизор. Если бы пульт был каким-то интеллектуальным устройством, которое показывало статус телевизора, тогда все 3 пульта дистанционного управления сообщали бы, что телевизор выключен (утилизирован) после того, как любой из них выключил его. Вы не можете увеличить громкость с помощью пульта 2 после выключения телевизора с помощью пульта 1
Вернуться к C#
В конечном итоге вызов .Dispose()
для любой из ссылок на переменную в текстовом поле удаляет само текстовое поле, а не ссылку на него. Идея оператора using
заключается в том, что он удаляет экземпляр объекта, который был установлен в круглых скобках. Вызов метода dispose для любых ссылок на переменные ваших имен в текстовом поле (mytextbox, myeventtextbox, sender - все ссылки на него) удалит само текстовое поле, поэтому, когда оператор using заканчивается и вызывается myeventtextbox.Dispose (), все другие ссылки на переменные становятся теперь связан с удаленным текстовым полем
Нам не нужно микроуправлять переменными в C#, как это могло бы быть в других языках. Ссылки на переменные очищаются, когда они выходят за пределы области видимости (когда выполнение выходит за пределы блока фигурных скобок, в котором была объявлена переменная). Когда больше нет уцелевших ссылок на объект в памяти, объект будет удален из памяти.
В этом случае sender
и myeventtextbox
перестанут существовать как ссылки на текстовое поле, когда обработчик событий завершит выполнение. Текстовое поле все еще сохранится, потому что mytextbox
все еще ссылается на него. Также к нему относится коллекция формы .Controls
. Если вы удалили элемент управления из .Controls
, а для mytextbox
было установлено значение null, больше не будет сохранившихся ссылок на текстовое поле, и оно будет удалено из памяти.
Чтобы понять эту проблему, вы сначала должны понять, как передаются объекты (ссылочные типы) в C#.
Как следует из их названия, когда вы передаете ссылочный тип, единственная информация, которую вы «копируете», - это его ссылка (которая, по сути, является адресом памяти в вашей оперативной памяти).
Итак, обе ваши переменные текстового поля указывают на один и тот же объект в вашей памяти.
Поэтому, когда оператор using заканчивается, ваше текстовое поле в вашем графическом интерфейсе освобождается.
Здесь mytextbox
и myeventtxtbox
указывают на один и тот же объект, потому что они являются ссылочными типами.
Что вам нужно, так это клон элемент управления. Думаю, вам поможет эта ссылка:
Клонировать элемент управления
Во время клонирования вы фактически копируете все свойства старого элемента управления в новый элемент управления.
Этот подготовил красивый метод расширения, который вы можете использовать для всех ваших элементов управления, включая TextBox.
что вы имеете в виду под освобожденным?