Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/125: Рейтинг темы: голосов - 125, средняя оценка - 4.60
28 / 28 / 5
Регистрация: 07.09.2012
Сообщений: 119

Как применить ref и out для ссылок на объекты

07.09.2012, 14:21. Показов 23509. Ответов 56
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите пожалуйста разобраться новичку. Читаю шилдта, никак не могу въехать.... С применением Ref & out для переменных типа значений все предельно ясно. А вот при для объектов не могу понять...
Как вижу все это я:
Типы значений: при передаче методу параметр получает копию значения аргумента. Соответственно, любые изменения в методе приводят к изменению копии аргумента, а значит, сам аргумент не изменяется. Все это исправляется при использования ref&out.
Ссылочный тип: при передаче методу параметр получает копию ссылки на объект. Т.е. сама ссылка передается по значению. Получается, наш объект теперь имеет "псевдонимы", и его можно изменять из метода.
Но что происходит при использовании ref с объектом???
Шилдт приводит пример с методом Swap, в котором изменяются ссылки на объекты.... (с 228)
Кто бы мне объяснил весь процесс по пунктам... а то никак не могу понять, что вообще там происходит.
Фраза: если модификаторы ref или out указывают на ссылку, то сама ссылка передается по ссылке - убила наповал)))
Спасибо заранее
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.09.2012, 14:21
Ответы с готовыми решениями:

Использование модификатора ref для ссылок на объекты (для чайника)
Всем привет! Изучаю c# по учебнику Шилдта, также разбираю примеры из него. Из примера ниже мне непонятно. Зачем здесь использовать...

Описать класс "Вектор" для хранения ссылок на объекты
Объявить класс "Вектор" для хранения ссылок на объекты. Класс должен иметь следующие поля: -массив ссылок, который может расти ...

Как можно в textarea применить ::first-line, или как к первой строки применить стиль, внутри данного элемента
Да и вообще, для этого можно ли еще что-либо вложить в данный элемент, кроме как текста? Добавлено через 2 часа 3 минуты вопрос...

56
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
07.09.2012, 14:27
при передаче ссылочного типа по ссылке (ref/out) вы можете изменить саму ссылку, без ref/out вы НЕ можете изменить саму ссылку, но можете изменить объект на который она указывает
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] A = new int[10];
            int[] B = new int[10];
            Console.WriteLine(A.Length + " " + B.Length);
            Ref(ref A);
            NotRef(B);
            Console.WriteLine(A.Length + " " + B.Length);
        }
        static void Ref(ref int[] A)
        {
            A = new int[5]; // это действие производится с самой ссылкой
        }
        static void NotRef(int[] A)
        {
            A = new int[5]; // а это - с копией ссылки
        }
    }
}
3
28 / 28 / 5
Регистрация: 07.09.2012
Сообщений: 119
07.09.2012, 14:46  [ТС]
Что то я еще больше запутался.... Вы говорите. что без ref я могу изменять объект - так почему же в програмке, написанной Вами, метод NotRef не меняет объект? может быть дело в том, что я не совсем понимаю механику самой передачи ссылок и копий ссылок и разницы между ними. Было бы здорово разобраться более подробно...
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
07.09.2012, 15:24
Вот моя тема
NotRef(int[] A) - создаем локальный массив
Ref(ref int[] A) - получаем ссылку на ссылку массива как-то так.

Добавлено через 10 минут
Цитата Сообщение от temcha Посмотреть сообщение
ref или out
создают ссылку на что-то.
Если это тип-значение ссылку на него(так как они не передаются а копируются каждый раз)
Если это ссылочный тип(который передается по ссылке),то создается ссылка на ссылку
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.09.2012, 15:24
temcha

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person
{
    public string Name { get; set; }
}
 
static void Main()
{
   Person p = new Person { Name = "Петя" };
   NoRef(p);
   Console.WriteLine(p.Name);
 
   Ref(ref p);
   Console.WriteLine(p.Name);
 
   Console.ReadLine();
}
 
static void NoRef(Person p)
{
   p = new Person { Name = "Вася" };
}
 
static void Ref(ref Person p)
{
   p = new Person { Name = "Вася" };
}
Так понятнее?
2
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
07.09.2012, 15:27
Цитата Сообщение от temcha Посмотреть сообщение
Что то я еще больше запутался.... Вы говорите. что без ref я могу изменять объект - так почему же в програмке, написанной Вами, метод NotRef не меняет объект? может быть дело в том, что я не совсем понимаю механику самой передачи ссылок и копий ссылок и разницы между ними. Было бы здорово разобраться более подробно...
объект это сам массив (его элементы), помимо объекта есть ссылка (собственно A), в строке
A=... изменяется не объект, изменяется ссылка
вы можете изменить объект (
C#
1
A[0]=5;
сработает) но изменить ССЫЛКУ вы не можете без ref потому что ее у вас нет (есть ее копия)
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
07.09.2012, 15:36
Цитата Сообщение от Tessen Посмотреть сообщение
сработает)
Вообще-то не сработает
0
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
07.09.2012, 15:42
Цитата Сообщение от Noob.net Посмотреть сообщение
Вообще-то не сработает
дааа нуу?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] A = new int[10];
            int[] B = new int[10];
            Console.WriteLine(A[0] + " " + B[0]);
            Ref(ref A);
            NotRef(B);
            Console.WriteLine(A[0] + " " + B[0]);
        }
        static void Ref(ref int[] A)
        {
            A[0] = 31;
        }
        static void NotRef(int[] A)
        {
            A[0] = 31;
        }
    }
}
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
07.09.2012, 15:46
Цитата Сообщение от Tessen Посмотреть сообщение
NotRef(B);
ну здесь как B[0] был равен 0,так и остался.
0
28 / 28 / 5
Регистрация: 07.09.2012
Сообщений: 119
07.09.2012, 15:48  [ТС]
kolorotur, спасибо за пример, но если бы мне было бы достаточно примера, я бы и с Шилдтом все разобрал... так что нет, не стало понятнее.
мне приводят примеры, а мне интересен механизм создания и изменения ссылок. Я понимаю, что создается ссылка на ссылку. Но как появление этой ссылки на ссылку может изменять первоначальную ссылку...
Объясните мне механизм изменения ссылок на примере из книги Шилдта:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
 
namespace ConsoleApplication1
{
    class RefSwap
    {
        int a, b;
 
        public RefSwap(int i, int j)
        {
            a = i;
            b = j;
        }
 
        public void Show()
        {
            Console.WriteLine("a: {0}, b: {1}", a, b);
        }
 
        public void Swap(ref RefSwap ob1, ref RefSwap ob2)
        {
            RefSwap t;
 
            t = ob1;
            ob1 = ob2;
            ob2 = t;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            RefSwap x = new RefSwap(1, 2);
            RefSwap y = new RefSwap(3, 4);
 
            Console.Write("X до вызова: ");
            x.Show();
            Console.Write("Y до вызова: ");
            y.Show();
 
            Console.WriteLine();
 
            x.Swap(ref x, ref y);
 
            Console.Write("X после вызова: ");
            x.Show();
            Console.Write("Y после вызова: ");
            y.Show();
            Console.ReadKey();
        }
        
    }
}
что происходит при вызове метода public void Swap(ref RefSwap ob1, ref RefSwap ob2) с самими ссылками?
0
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
07.09.2012, 15:49
странно, а следующая за ним строчка
C#
1
Console.WriteLine(A[0] + " " + B[0]);
утверждает что B[0] как был равен нулю так и стал равен 31, кому верить?
запускать то пробовали?
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.09.2012, 15:49
Цитата Сообщение от Noob.net Посмотреть сообщение
ну здесь как B[0] был равен 0,так и остался.
С чего это вдруг?
1
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
07.09.2012, 15:51
Сорри я де-ил у меня очепятка была
У меня такой же пример был,что не делаю - не меняет..Думаю может студия вещь говорит,а оказалось руки)
0
3 / 3 / 0
Регистрация: 03.06.2012
Сообщений: 38
07.09.2012, 16:02
kolorotur,
Написал такой код по подобию вашего
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Text = "Петя";
        }
 
        private void button1_Click(object sender, EventArgs e)
        {          
            NoRef(label1);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            Ref(ref label1);
        }
 
 
        static void NoRef(Label l)
        { 
            l = new Label { Text= "Вася" };
        }
 
        static void Ref(ref Label l)
        {          
            l = new Label { Text = "Вася" };
        }
Но Label1 не меняется, какую бы я одну из двух кнопок не нажимал.
Что не так? Вроде бы подход тот же.
0
28 / 28 / 5
Регистрация: 07.09.2012
Сообщений: 119
07.09.2012, 16:06  [ТС]
оу, ребята, прошу вас общаться в других темах. Я реально не могу понять и очень надеюсь на объяснения...
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.09.2012, 16:09
Цитата Сообщение от temcha Посмотреть сообщение
мне интересен механизм создания и изменения ссылок. Я понимаю, что создается ссылка на ссылку. Но как появление этой ссылки на ссылку может изменять первоначальную ссылку...
Давайте сначала разберемся в том, что такое объекты и ссылки на них с точки зрения памяти.
Объект - это место в памяти, где хранятся собственно данные.
Ссылка - это другое место в памяти, где хранится адрес объекта, то есть адрес собственно данных.
Так как ссылка - это тоже место в памяти, то у этого места, разумеется, тоже есть адрес.

Допустим, есть некий объект Х, хранящийся по адресу 0хFF
На него есть ссылка, хранящаяся по адресу 0xAA - это значит, что значение ячейки памяти, распологающейся по адресу 0xAA равно 0xFF. То есть в этой ячейке хранится адрес объекта.
При передаче ссылки в метод создается копия этой ссылки, то есть где-то в памяти выделяется новая ячейка, хранящая адрес на тот же самый объект.
При передаче этой ссылки в метод NoRef создается новая переменная по адресу, скажем, 0xF8, в которой хранится значение 0xFF - адрес объекта. Если записать что-нибудь другое в ячейку по адресу 0xF8, то это никак не повлияет на то, что записано по адресу оригинальной ячейки 0xAA.
При передаче этой ссылки в метод Ref, новая переменная не создается, а просто передается адрес уже существующей ячейки: 0xAA, то есть адрес оригинальной ссылки. Разумеется, если в этом месте памяти записать что-нибудь левое, то это повлияет на все переменные, использующие эту ячейку для хранения адреса собственно данных.
1
3 / 3 / 0
Регистрация: 03.06.2012
Сообщений: 38
07.09.2012, 16:09
Цитата Сообщение от temcha Посмотреть сообщение
оу, ребята, прошу вас общаться в других темах. Я реально не могу понять и очень надеюсь на объяснения..
Так и я о том же. Вопрос про тот же ref.
0
28 / 28 / 5
Регистрация: 07.09.2012
Сообщений: 119
07.09.2012, 16:35  [ТС]
kolorotur, с этим более-менее ясно. Но возникают новые вопросы: с точки зрения памяти, аргумент, который передается и параметр метода - одна и та же переменная?
Вы говорите
При передаче этой ссылки в метод Ref, новая переменная не создается, а просто передается адрес уже существующей ячейки: 0xAA, то есть адрес оригинальной ссылки. Разумеется, если в этом месте памяти записать что-нибудь левое, то это повлияет на все переменные, использующие эту ячейку для хранения адреса собственно данных.
глупый вопрос - чему передается адрес уже существующей ячейки, ии что значит "в этом месте памяти"...?
0
3 / 3 / 0
Регистрация: 03.06.2012
Сообщений: 38
07.09.2012, 16:47
И все таки
0
 Аватар для Евгений В
912 / 672 / 134
Регистрация: 01.03.2010
Сообщений: 1,279
07.09.2012, 16:52
temcha,

Возьмем фрагмент примера от colorotur

C#
1
2
3
4
static void NoRef(Person p) // название может быть любое, не только p
{
   // пока пусто
}
Теперь у нас две ссылки на один и тот же объект p
Первая ссылка после - Person p = new Person { Name = "Петя" };
Вторая после static void NoRef(Person p) (копия первой)

Теперь есть два варианта:
1. Повторю, и ссылка и ее копия ссылаются на один и тот же объект p
Следовательно, работая с любой из них можно одинаково менять объект p

C#
1
2
3
4
static void NoRef(Person p)
{
    p.Name = "Вася" ;
}
Все, теперь p поменяется на Васю

2. Можно заставить копию ссылки ссылаться на другой объект. Тогда к прошлому объекту p
она отношения уже иметь не будет
C#
1
2
3
4
static void NoRef(Person p)
{
   p = new Person { Name = "Вася" };
}
Вот почему в примере от от colorotur в первом случае имя не поменяется. Ссылка уже не работает с прошлым объектом.


При работе с ref копия не создается. Что передали, с тем и работаем.

Поэтому в примере Шилдта можно было поменять ссылки местами через посредника],
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.09.2012, 16:52
Помогаю со студенческими работами здесь

Перебор ссылок на объекты
Здравствуйте, у меня имеется объект (корабль линкор). Перебираю с помощью for. Так как объект может быть уничтожен другим объектом, на его...

Vector ссылок на объекты класса
У меня есть свой класс объекта. И при создании новых экземпляров данного объекта, мне нужно чтобы в vector заносилась ссылка на него...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru