ref и out в C#
Всем доброго времени суток, на связи Алексей Гулынин. В прошлой статье мы узнали про перегруженные методы в C#. В данной статье я бы хотел поговорить про ключевые слова ref и out в C#. Использование этих ключевых слов приводит к тому, что параметр начинает передаваться не по значению, а по ссылке. Ключевое слово out обозначает почти то же самое, что и ref. Параметр, перед которым указываются данные операторы, тоже передаётся по ссылке, т.е. в переменной хранится адрес этого параметра. В чем разница же между ref и out? Разница в том, что out позволяет вам передать ссылку на переменную неинициализированную, а ref — только на инициализированную.
Давайте на примере разберем, что это значит. Создадим метод, который будет принимать числовой параметр. В данном методе этот параметр будем увеличивать и выводить значение. В методе Main() создадим параметр с этим же именем и будем также выводить его значение:
static void Main(string[] args) { int param = 10; testMethod(param); //Выйдет значение = 11 Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 10 Console.ReadLine(); } static void testMethod(int param) { param++; Console.WriteLine("Значение переменной param в методе testMethod = {0}", param); }
Во втором случае вышло 10, потому что int — это ValueType (это когда параметр передаётся по значению), это значит, что при выполнении команды testMethod(param) метод testMethod() будет работать с копией переменной param (в данный момент происходит копирование переменной в стеке), что никак не повлияет на переменную param, которая была объявлена в методе Main(). Модифицируем наш код, добавив оператор ref перед переменной в методе testMethod(). Обратите внимание, что при вызове данного метода нужно также ставить оператор ref:
static void Main(string[] args) { int param = 10; testMethod(ref param); //Выйдет значение = 11 Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 11 Console.ReadLine(); } static void testMethod(ref int param) { param++; Console.WriteLine("Значение переменной param в методе testMethod = {0}", param); }
Теперь программа в обоих случаях выводит 11. Тут дело в том, что мы в стек (это область памяти в пространстве адресов) загоняем ссылку на область памяти, где находится переменная param, и в методе testMethod() мы уже работаем не с копией, а с тем же самым параметром param, что и в методе Main(). Те изменения, которые мы провели с переменной param в методе testMethod() будут видны и снаружи (за областью видимости метода).
Внесем изменения в наш код. Просто объявим переменную param, но не будем её инициализировать, т.е. вместо строки int param = 10; запишем int param;. Компилятор старается контролировать использование неинициализированных переменных вы даст ошибку в этом случае. Мы пытаемся переменную, которая не содержит никаких значений, передать в метод и там с ней выполнять определенные действия, но так делать нельзя. А что делать если инициализация переменной выполняется как раз в этом методе?
В этом случае как раз и используют out:
static void Main(string[] args) { int param; testMethod(out param); //Выйдет значение = 11 Console.WriteLine("Значение переменной param в методе Main = {0}", param); //Выйдет значение = 11 Console.ReadLine(); } static void testMethod(out int param) { param = 10; param++; Console.WriteLine("Значение переменной param в методе testMethod = {0}", param); }
Теперь в методе testMethod() обязательно нужно проинициализировать переменную param.
В данной небольшой статье вы узнали про ключевые слова ref и out в C#.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.
Читаю троелсона , очень сложно объяснил про ref and out , но тут реально легко понимается , спасибо за статью , почитаю у вас еще