Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка - Основи Програмування C_.doc
Скачиваний:
46
Добавлен:
18.12.2018
Размер:
1.44 Mб
Скачать

Методи в мові с#.

1. Передача об’єктів методам.

Раніше вже було наголошено, що звичайні змінні value-типу передаються у метод за значенням, а змінні reference-типу – за посиланням. Також обговорювались відмінності передачі через список параметрів методу змінних-значень та змінних-посилань. Для детальнішого розуміння цієї різниці розглянемо наступний простий приклад. В ньому визначається класс MyClass, який містить цілу змінну i та конструктор, що її ініціалізує значенням свого параметру. У класі Program визначені 2 функції – MyFunc1 та MyFunc2, перша з яких збільшує на одиницю свій цілочислений параметр, а друга – інкрементує член класу MyClass . У функції Main змінна i ініціалізується значенням 10, а також створюється екземпляр класу MyClass, змінна і в якому має те саме значення 10.

using System;

namespace Object_Param

{

class MyClass

{

public int i; // Просто ціла змінна

public MyClass(int i_) // Конструктор класу

{ i = i_; }

}

class Program

{ // Функція одержує параметр by-value

static void MyFunc1(int val)

{ val++; }

// Функція одержує об'єкт by-referebce

static void MyFunc2(MyClass m)

{ m.i++; }

static void Main( )

{

int i = 10; // Ціла змінна із значенням 10

MyClass m = new MyClass(10);

Console.WriteLine("Перед MyFunc1: ");

Console.WriteLine("Змiнна i = " + i); // Друкуємо і

MyFunc1(i); // У функції MyFunc1 і збільшилась

Console.WriteLine("Пiсля MyFunc1: ");

// Але тут і не змінилась!

Console.WriteLine("Змiнна i = " + i);

Console.WriteLine("Перед MyFunc2: ");

Console.WriteLine("Змiнна i = " + m.i);// Друкуємо і

MyFunc2(m); // У функції MyFunc2 і збільшилась

// Тут і дійсно збільшилась

Console.WriteLine("Пiсля MyFunc2: ");

Console.WriteLine("Змiнна i = " + m.i);

}

}

}

Після запуску програми одержуємо наступний результат.

Перед MyFunc1:

Змiнна i = 10

Пiсля MyFunc1:

Змiнна i = 10

Перед MyFunc2:

Змiнна i = 10

Пiсля MyFunc2

Змiнна i = 11

Цей результат показує, що функція MyFunc1, яка одержала параметр i за значенням, не мала доступу до самого аргументу i, використовуючи лише його значення 10, на відміну від функції MyFunc2, яка одержала об’єкт за посиланням, а отже всі зміни, виконані функцією над своїм параметром, реально відбулись з об’єктом. Причина цього полягає у тому, що параметр m функції MyFunc2 є посиланням на об’єкт MyClass. І хоча сам аргумент m передається у функцію за значенням, проте його значення – це адреса розташування екземпляра MyClass у пам’яті, а отже, функція має доступ до членів цього об’єкту.

Щоб підкреслити важливість виділеної у попередньому абзаці фразі, розберемо ще один приклад. В цьому прикладі функція MyFun1 на перший погляд міняє місцями 2 об’єкти. Точніше кажучи, вказівники на два об’єкти. У функції ж MyFun2 міняються місцями значення членів двох об’єктів класу MyClass. З’ясуємо, як зміняться значення об’єктів autumn та winter – екземплярів класу MyClass після викликів цих функцій.

using System;

namespace Object_Param_1

{

class MyClass

{

public string text;

public MyClass(string s) // Конструктор класу

{ text = s; }

}

class Program

{

static void MyFun1( MyClass m1, MyClass m2)

{ // Переставляємо об'єкти

MyClass m = m1;

m1 = m2;

m2 = m;

}

static void MyFun2(MyClass m1, MyClass m2)

{ // Переставляємо змінні об'єктів

string s = m1.text;

m1.text = m2.text;

m2.text = s;

}

static void Main()

{

MyClass autumn = new MyClass("осiнь");

MyClass winter = new MyClass("зима");

MyFun1(autumn, winter); // Чи помінялись об'єкти?

Console.WriteLine("Пiсля MyFun1:");

Console.WriteLine(autumn.text); // Це зима? - Ні!

Console.WriteLine(winter.text); // Це осінь? - Ні!

// Чи помінявся зміст об'єктів?

MyFun2(autumn, winter);

Console.WriteLine("Пiсля MyFun2:");

Console.WriteLine(autumn.text); // Це зима? - Так!

Console.WriteLine(winter.text); // Це осінь? - Так!

}

}

}

Після запуску програми на екрані побачимо:

Пiсля MyFun1:

осінь

зима

Пiсля MyFun2:

зима

осінь

Цей приклад ще раз демонструє, що одержавши за значенням вказівники на об’єкти, функції мають змогу змінювати їх зміст, проте не мають змоги змінити самі вказівники.