Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
1

Только из-за удобства ли используют ref вместо return

12.11.2012, 20:27. Показов 4562. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Изучаю C# по самоучителю, не могу окончательно понять использование return, out и ref на практике, а именно:
1. Если нужно изменить значение, то используют ref вместо return - только из-за удобства?
2. Выходные параметры out и ref похожи, но существуют различия - "out применяют, если переменная не инициализированная" (зачем, вроде немного понятно), ?НО "в функции, которая использует параметр out, должно предполагаться, что ему не присвоено никакое значение" - здесь для меня сплошной туман! - Зачем производить операцию над переменной, если она без значения? Как и где это используется на практике?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.11.2012, 20:27
Ответы с готовыми решениями:

Что быстрее - ref или return?
Здравствуйте! Интересует вопрос, будет ли функция работать быстрее если в качестве параметра...

Написать метод с использованием return, out, ref
Ввести матрицы А(4, 4) и В(3, 3). Решить уравнение cx+d=0, где с – минимальный элемент матрицы А, d...

Определить, у какого из прямоугольных треугольников периметр больше (return, ref, out)
Два прямоугольных треугольника заданы своими катетами. Определить, у какого из них периметр больше....

Можно ли вместо return использовать echo?
собственно вот в чем вопрос имется такая функция function...

15
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
12.11.2012, 20:40 2
пример:
http://msdn.microsoft.com/ru-r... c0zb1.aspx
из метода возвращаются два значения, одно bool = успешность преобразования (удалось / не удалось)
2е - собственно значение если удалось

без ref/out вы что возвращать предлагает? структуру из bool и double? сложнее и непонятнее, тем более что для каждого метода возвращающего более 1 значения придется создавать свою структуру

out - параметр для передачи его ИЗ метода, во-первых вам просто компилятор не даст его оставить неинициализированным
почему должно предполагаться что ему не присвоено значение?
очень просто, потому что это МОЖЕТ БЫТЬ так
"out применяют, если переменная не инициализированная" (зачем, вроде немного понятно)
представьте что вы это используете, но 2ой части, а именно
в функции, которая использует параметр out, должно предполагаться, что ему не присвоено никакое значение"
нет, что произойдет? в таком случае вы сможете написать что то вроде этого:
C#
1
2
3
4
5
6
7
8
9
10
11
public static Main()
{
int q;
Method(q);
}
 
public void Method(out i)
{
if (i==10) //именно здесь компилятор ругнется сообщив что параметр i не инициализирован
i=11;
}
и компилятор это пропустил бы, если б не 2ое утверждение про предположение в функции
соответственно вы бы это тоже могли пропустить, скомпилировать проект, запустить и только в том случае если этот метод будет выполняться поймать исключение во время исполнения (насколько труднее отлавливать ошибки исполнения, нежели компиляции объяснять надо?)
0
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
12.11.2012, 21:46  [ТС] 3
Цитата Сообщение от Tessen Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
public static Main()
{
int q;
Method(q);
}
 
public void Method(out i)
{
if (i==10) //именно здесь компилятор ругнется сообщив что параметр i не инициализирован
i=11;
}
Почему в функции Main указан Method (q), а не Method (out q)? И сама функция находится вначале Methoda?
0
713 / 680 / 126
Регистрация: 30.03.2012
Сообщений: 1,124
12.11.2012, 21:56 4
потому что это пример который я набирал на форуме, а не в студии
действительно нужен out, не обратил внимание
суть то все равно понятна?
0
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
12.11.2012, 23:08  [ТС] 5
Суть понятна, но я не могу понять как и почему в реальных прогах используется out вместо ref. Насколько он полезен на практике? В Вашем последнем примере, зачем нужно было не инициализировать i?

И про возвращаемый параметр return: его в отличии от ref удобней использовать как результат функции? а ref только как ссылку на параметр?
0
Эксперт .NET
17686 / 12872 / 3365
Регистрация: 17.09.2011
Сообщений: 21,138
12.11.2012, 23:15 6
Цитата Сообщение от Valerich555 Посмотреть сообщение
я не могу понять как и почему в реальных прогах используется out вместо ref.
Причина очень проста: out - это гарантия того, что значение переданной переменной будет изменено в методе, куда она передается, в то время как ref такого не гарантирует.
Именно поэтому переменные можно передавать через out, предварительно не проиницализировав. Тем самым, кстати, возможно сэкономя пару инструкций на лишнюю инициализацию.
0
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
13.11.2012, 08:26  [ТС] 7
Цитата Сообщение от kolorotur Посмотреть сообщение
Причина очень проста: out - это гарантия того, что значение переданной переменной будет изменено в методе, куда она передается, в то время как ref такого не гарантирует.
Именно поэтому переменные можно передавать через out, предварительно не проиницализировав. Тем самым, кстати, возможно сэкономя пару инструкций на лишнюю инициализацию.
Т.е. на практике ref обычно не используют? только out?
0
Эксперт Java
4091 / 3825 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
13.11.2012, 09:07 8
Цитата Сообщение от Valerich555 Посмотреть сообщение
Т.е. на практике ref обычно не используют? только out?
Нет, используют и то, и то, в зависимости от требований.
Вам объясняли, зачем нужен out, если есть ref.
0
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
13.11.2012, 13:43  [ТС] 9
Цитата Сообщение от turbanoff Посмотреть сообщение
Нет, используют и то, и то, в зависимости от требований.
Вам объясняли, зачем нужен out, если есть ref.
Без обид, но у меня складывается ощущение, что я задал вопрос типа: "Что появилось раньше курица или яйцо?"
Чем ref в общих чертах отличается от out я понял, вопрос был: зачем на ПРАКТИКЕ использовать ref, если есть out?
0
12 / 12 / 3
Регистрация: 30.11.2011
Сообщений: 76
13.11.2012, 13:56 10
Я для себя уяснил так - если нужно получить из метода более одного значения, и эти значения инициализируются и вычисляются в САМОМ МЕТОДЕ, то нужно использовать out, а если эти значения инициализируются и используются где-то раньше (до вызова метода), и могут быть изменены в методе, а могут и не меняться, нужно использовать ref. Если возвращаемое значение у метода одно, то просто return
0
Эксперт .NET
17686 / 12872 / 3365
Регистрация: 17.09.2011
Сообщений: 21,138
13.11.2012, 14:02 11
Цитата Сообщение от Valerich555 Посмотреть сообщение
зачем на ПРАКТИКЕ использовать ref, если есть out?
Так затем, что out обязывает изменять этот параметр в методе.
А если изменять его по каким-то причинам не нужно? Ну вот условие в методе: если "а", то изменить, а если "б", то оставить как есть. С out такое не прокатит.
0
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
13.11.2012, 14:15  [ТС] 12
Цитата Сообщение от kolorotur Посмотреть сообщение
Так затем, что out обязывает изменять этот параметр в методе.
А если изменять его по каким-то причинам не нужно? Ну вот условие в методе: если "а", то изменить, а если "б", то оставить как есть. С out такое не прокатит.
Начинаю немного понимать.. но не полностью... Оставлю этот вопрос открытым, когда будет много практики, тогда пойму окончательно :-)
0
Эксперт .NET
17686 / 12872 / 3365
Регистрация: 17.09.2011
Сообщений: 21,138
13.11.2012, 14:20 13
Valerich555, да там понимать-то нечего: out и ref передают в метод не копию, а ту же самую переменную. Единственная разница в том, что out обязывает метод, в который она передается, присвоить ей какое-то значение, а ref - не обязывает.
Из этого так же следует, что переменную, которую нужно передать в метод с out, не обязательно перед этим инициализировать, т.к. это 100% будет сделано в методе. Но это уже так, бонус.

Всё, никаких таинств и секретов тут больше нет - вы используете тот оператор, который считаете более подходящим для вашей задачи. Никто вас не обязывает использовать какой-то определенный из них.
1
0 / 0 / 0
Регистрация: 28.09.2012
Сообщений: 24
14.11.2012, 13:45  [ТС] 14
В моём самоучителе написано, что ref также как и out присваивает значение переменной, а return не присваивает.. И приведен пример отличия return от ref, а вот - про ref от out , без примера...
Я не понимаю, почему вы пишите, что ref не обязывает присвоить ей значения, когда оно присваивается?
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
14.11.2012, 14:24 15
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
 
namespace ConsApp_RefOut
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person1 = new Person() { Age = 18, Name = "Изначально созданный" };
            Console.WriteLine("Вызываем метод: GetPersonWithoutRefOrOut");
            //Созданный объект внутри метода "так и останется внутри метода"
            GetPersonWithoutRefOrOut(person1); 
 
            Console.WriteLine("Результат его работы:");
            Console.WriteLine(person1);
            Console.WriteLine("Как видно созданный объект внутри метода не передался" +
                " за его пределы, так как на него ссылалась копия ссылки Person\n");
 
            Person person2;
 
            GetPersonRef(ref person1); //передаём уже проинициализированную ссылку
            GetPersonOut(out person2); //передаём НЕ проинициализированную ссылку
 
            Console.WriteLine(person1);
            Console.WriteLine(person2);
 
            string text; //нет смысла инициализировать, только для передачи в метод
            if (TryReadText(out text, "Бла-бла-бла"))
                Console.WriteLine(Environment.NewLine + text);
            else
                Console.WriteLine(Environment.NewLine + "Текст не удалось прочитать");
 
            Console.ReadKey();
        }
 
        public static bool TryReadText(out string text, string filePath)
        {
            if (File.Exists(filePath))
            {
                text = File.ReadAllText(filePath);
                return true;
            }
            text = string.Empty;
            return false;
        }
 
        //передаётся копия ссылки Person
        public static void GetPersonWithoutRefOrOut(Person person) 
        {   
            person = new Person() { Age = 90, Name = "Из метода GetPersonWithoutRefOrOut" };
        }
 
        //передаётся ссылка по ссылке, но передаваемая ссылка
        //должна быть инициализирована хотя бы null
        public static void GetPersonRef(ref Person person)
        {
            person = new Person() { Age = 20, Name = "Из метода ref" };
        }
 
        //передаётся ссылка по ссылке, но передаваемая ссылка
        //может быть не инициализирована
        public static void GetPersonOut(out Person person) 
        {
            person = new Person() { Age = 30, Name = "Из метода out" };
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
    public class Person
    {
        public override string ToString()
        {
            return string.Format("Возраст: {0} Имя: {1}", Age, Name);
        }
 
        public string Name { get; set; }
        public uint Age { get; set; }
    }
Добавлено через 1 минуту
Цитата Сообщение от Valerich555 Посмотреть сообщение
Я не понимаю, почему вы пишите, что ref не обязывает присвоить ей значения, когда оно присваивается?
Для передачи методу переменной через ref, нужно сначала проинициализировать переменную, а потом уже передавать в метод, иначе не скомпилится. Внимательно посмотри код, что я выложил, там показаны отличия. Скопируй себе и пройдись по коду в режиме отладки по шагам и смотри что происходит.
0
Эксперт .NET
17686 / 12872 / 3365
Регистрация: 17.09.2011
Сообщений: 21,138
14.11.2012, 14:37 16
Цитата Сообщение от Valerich555 Посмотреть сообщение
Я не понимаю, почему вы пишите, что ref не обязывает присвоить ей значения, когда оно присваивается?
Встречный вопрос: кто вас обязывает писать на форум? Вы ведь пишите - значит, кто-то обязывает!
При ref переменная в методе может меняться, а может и не меняться, а при out - меняется обязательно, иначе код просто не скомпилируется.

C#
1
2
3
4
5
6
7
8
9
void Foo(ref int x)
{
    Console.WriteLine("А вот не буду я ничего здесь менять! Не хочу и не буду!");
}
 
void Foo(out int x)
{
   Console.WriteLine("А вот не буду я ничего здесь менять! Не хочу и не буду!"); //  "Щщаз, размечтался!" (c) csc.exe
}
0
14.11.2012, 14:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2012, 14:37
Помогаю со студенческими работами здесь

Насколько разумно использовать throw вместо return
Насколько разумно использовать throw вместо return? И является ли throw более медленным?

Какой оператор можно использовать в конструкторах вместо return
Какой оператор можно использовать в конструкторах вместо return; вопрос в заголовке

Существуют ли какие-то инженерные задачи, которые используют только диагонально преобладающие матрицы
Скажите, пожалуйста, существуют ли какие-то инженерные задачи, которые используют только...

Перегрузка функция отличающихся только return
QVector<float> parseLogAttr(QString name_); QVector<int> parseLogAttr(QString name_); ...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru