Копия объекта исчезает при использовании оператора using - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь понять, как работает оператор 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 (копия) должна быть выпущена.

Я действительно кое-что здесь упускаю, не могли бы вы помочь мне?

Ответы [ 4 ]

0 голосов
/ 17 декабря 2018

Здесь mytextbox и myeventtxtbox указывают на один и тот же объект, поскольку они являются ссылочными типами.

Вам нужно клонировать элемент управления.Полагаю, эта ссылка поможет вам:

Клонировать элемент управления

Во время клонирования вы фактически копируете все реквизиты старого элемента управления на новый элемент управления.

Этот подготовил прекрасный метод расширения , который можно использовать для всех элементов управления, включая TextBox

0 голосов
/ 17 декабря 2018

Я думаю, проблема в том, что вы предполагаете следующее:

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, больше не будет сохраняющихся ссылок на текстовое поле, и он будет удален из памяти

.
0 голосов
/ 17 декабря 2018

Чтобы понять эту проблему, вы должны сначала понять, как передаются объекты (ссылочные типы) в C #.

Как следует из их названия, когда вы передаете ссылочный тип, единственная информация, которую вы копируете"является его ссылкой (который в основном является адресом памяти в вашей оперативной памяти).

Таким образом, обе ваши переменные текстового поля указывают на один и тот же точный объект в вашей памяти.

Поэтому, когда оператор using заканчивается, ваше текстовое поле в графическом интерфейсе освобождено.

0 голосов
/ 17 декабря 2018

Это ссылочные типы.Итак, myeventtxtbox ничего не копирует.И mytextbox, и myeventtxtbox указывают на один и тот же объект, и единственное различие между ними заключается в названии ссылки.На основе this :

Типы ссылок используются ссылкой, которая содержит ссылку (адрес) на объект, но не сам объект.Поскольку ссылочные типы представляют адрес переменной, а не сами данные, присвоение ссылочной переменной другой не копирует данные.Вместо этого он создает вторую копию ссылки, которая ссылается на то же местоположение кучи, что и исходное значение .Переменные ссылочного типа хранятся в другой области памяти, которая называется кучей.Это означает, что когда переменная ссылочного типа больше не используется, ее можно пометить для сборки мусора.

Следующие сообщения также могут быть интересны:

Что такоеРазница между ссылочным типом и типом значения в c #?

Мелкая копия или Глубокая копия?

...