Опубликован: 25.03.2010 | Уровень: для всех | Доступ: платный
Лекция 8:

Основы языка C#. Часть 2

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Аннотация: В данной лекции описываются такие понятия как передача параметров методам по ссылке и по значению.

Модификаторы параметров методов

В языке C# существуют два типа переменных - типы, характеризуемые значением и ссылочные типы. Переменные типа значения содержат именованные данные, к которым относятся все числовые типы, структуры и перечисления. Они создаются при компиляции программы и размещаются в стековой области памяти при их загрузке. Ссылочные типы содержат адреса участков памяти, создаваемых динамически при выполнении программы, и представляют неименованные данные.

Таблица 8.1 . Объекты типа значения и ссылки
Объявление типа Создание объекта Альтернативный синтаксис создания объекта
Встроенный тип, характеризуемый значением int a; int a = new int();
Пользовательский тип, характеризуемый значением struct MyStruct { public x, y; } MyStruct point; MyStruct point = new MyStruct();
Пользовательский тип, характеризуемый ссылкой
struct MyClass
{
    public x, y;
}
// Объявили ссылку 
MyClass point; 
// Создали и привязали объект 
point = new MyClass();
MyClass point = new MyClass();

На случай применения одинакового синтаксиса конструктор по умолчанию без параметров за типами значений зарезервирован и его переопределять нельзя. Можно только дополнить тип параметризованными конструкторами.

При выполнении операции присваивания в переменные типа значений копируются сами данные, в переменные типа ссылок копируется адрес расположения одних и тех же данных.

В C# формальные параметры метода при его объявлении называют просто параметрами, а фактические параметры, передаваемые методу при его вызове - аргументами. Статические методы и методы экземпляра могут использовать параметры, передаваемые как аргументы вызывающей стороной (клиентами класса). В C# предлагается множество модификаторов параметров, которые обеспечивают контроль со стороны компилятора за действиями программиста при вызове этих методов и передаче им фактических аргументов.

Таблица 8.2 . Модификаторы параметров в C#
Модификатор Описание
(нет) Если параметр метода не помечен модификатором, то предполагается передача параметра по значению, т.е. в вызываемый метод передается копия оригинальных данных
out Выходной параметр устанавливается вызываемым методом и передается по ссылке. Если вызываемый метод не присвоит выходному параметру значение, то генерируется ошибка компиляции
params Позволяет переслать произвольное число аргументов одинакового типа в виде единого параметра. Для любого метода допускается только один модификатор params и только для последнего по порядку следования параметра
ref Передается ссылка на данные клиента, которые метод может менять внутри себя. Фактически метод работает с данными, размещенными вне его

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

Входные параметры, представленные значением

При передаче именованного параметра он передается по значению, т.е. внутри метода создается копия подключенных данных и метод работает с этой копией. Оригинальные данные клиента метода не меняются и вызывающая сторона не увидит выполненных изменений. Это самый безопасный способ передачи, когда по исходным данным нужно получить какой-то результат, оставив сами данные без изменений.

Приведем простой пример.

using System;
    
static class Calculator
{
    public static int Add(int x, int y, int a, int b)
    {
        int answer = x + y;
        x = 10; y = 20; a = 30; b = 40;
        return answer;
    }
}
    
class Start
{
    static void Main()// Вызывающая сторона
    {
        // Настройка консоли
        Console.Title = "Передача параметров по значению";
        Console.ForegroundColor = ConsoleColor.White;
        Console.CursorVisible = false;
    
        int x = 1, y = 2, a = 3, b = 4;
        Console.WriteLine("До вызова: \tx={0}; y={1}; a={2}; b={3}",
            x, y, a, b);
        Calculator.Add(x, y, a, b);
        Console.WriteLine("После вызова: \tx={0}; 
          y={1}; a={2}; b={3}",
            x, y, a, b);
    
        Console.ReadLine();
    }
}
Листинг 8.1 . Передача параметров по значению

Результат будет таким


Мы видим, что переприсваивание значений параметрам внутри метода не влияет на изменения данных, хранящихся в вызывающей стороне, поскольку метод работает с копиями.

Следует отметить, что когда методу передается ссылка на объект, то метод всегда работает с внешними данными, то есть с самим объектом.

Выходные параметры, представленные значением

Часть параметров, которым планируется внутри метода выполнить изменения значений, следует обозначать как выходные с помощью ключевого слова out. Это требуется делать и в объявлении метода, и в его вызове.

Пометим в предыдущем примере два параметра как выходные. Код будет таким

using System;
    
static class Calculator
{
    public static int Add(int x, int y, out int a, out int b)
    {
        int answer = x + y;
        x = 10; y = 20; a = 30; b = 40;
        return answer;
    }
}
    
class Start
{
    static void Main()// Вызывающая сторона
    {
        // Настройка консоли
        Console.Title = "Применение выходных параметров";
        Console.ForegroundColor = ConsoleColor.White;
        Console.CursorVisible = false;
    
        int x = 1, y = 2, a = 3, b = 4;
        Console.WriteLine("До вызова: \tx={0}; 
          y={1}; a={2}; b={3}",
            x, y, a, b);
        Calculator.Add(x, y, out a, out b);
        Console.WriteLine("После вызова: \tx={0}; 
          y={1}; a={2}; b={3}",
            x, y, a, b);
    
        Console.ReadLine();
    }
}
Листинг 8.2 . Применение выходных параметров

Выполним пример


Мы видим, что отмеченные как выходные параметры меняют в вызывающем коде свои значения. Им в клиенте не обязательно присваивать значения, все равно метод их изменит.

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?

Денис Пашков
Денис Пашков
Россия
Татьяна Ковалюк
Татьяна Ковалюк
Украина, Киев, Киевский политехнический институт, 1974