Paweł Łukasiewicz
2015-03-13
Paweł Łukasiewicz
2015-03-13
Udostępnij Udostępnij Kontakt
Metoda do grupa poleceń, która ma wykonanać pewne, określone działanie. Każdy program w języku C# zawiera co najmniej jedną klasę z metodą nazwną Main().

Aby użyć metody należy ją:
  • zdefiniować;
  • wywolać.

Definiowanie metod

Podczas definicji metody należy określić elementy jej struktury.
Składnia:
modyfikator_dostepu zwracany_typ nazwa_metody (lista_parametrów)
{
    wnętrze_metody
}

Poniżej szczegółowe omówienie wszystkich elementów metody:
  • modyfikator_dostępu - definiuje widoczność zmiennej lub metod;
  • zwracany_typ - metoda może zwracać wartość. Typ ten określa jaki rodzaj wartości zostanie zwrócony. Jeżeli metoda nie zwraca określonej wartości, to typem zwracanym jest void;
  • nazwa_metody - nazwa metody jest unikatowa oraz ważna jest wielkość liter (case sensitive). Nazwa taka nie może być identyczna z pozostałmi identyfikatorami zdefniowanymi w klasie;
  • lista_parametrów - parametry umieszczone są w nawiasie. Pozwalają one na przekazywanie oraz zwracanie danych z metody. Lista parametrów danej metody odnosi się do typu, kolejności oraz liczby parametrów w metodzie. Parametry są opcjonalne, metoda nie musi ich zawierać w swojej definicji;
  • wnętrze_metody - zawiera zestaw poleceń niezbednych do wykonania określonego działania.

Przykład:
class WyborWiekszejLiczby
{
    public int ZnajdzMax(int a, int b)
    {
        // lokalna deklaracja typu zwracanego
        int wynik;
        if (a > b)
            wynik = a;
        else
            wynik = b;
        return wynik;
    }
}

Powyższy przykład pokazuję metodę ZnajdzMax(), która przyjmuje dwie wartości całkowite oraz zwraca większą z nich. Modyfikator dostępu metody to public, dzięki czemu mam do niej dostęp z zewnątrz klasy używając instancji tej klasy.

Wywoływanie metod

Metoda może zostać wywołana przy użyciu jej nazwy. Poniższy przykład pokazuje takie wywołanie:
using System;
namespace Metody
{
    class Program
    {
        static void Main(string[] args)
        {
            // Definicja zmiennych lokalnych
            int a = 23;
            int b = 212;
            int wynik_porownania;
            WyborWiekszejLiczby wbl = new WyborWiekszejLiczby();
            wynik_porownania = wbl.ZnajdzMax(a, b);
            Console.WriteLine("Wieksza liczba to: {0}", wynik_porownania);
            Console.ReadKey();
        }
    }
    class WyborWiekszejLiczby
    {
        public int ZnajdzMax(int a, int b)
        {
            // lokalna deklaracja typu zwracanego
            int wynik;
            if (a > b)
                wynik = a;
            else
                wynik = b;
            return wynik;
        }
    }
}

Rekurencyjne wywoływanie metod

Metoda może wywoływać się sama. Zachowanie takie to rekurencja.
Poniższej przykład obliczający silnie danej liczby używając do tego rekurencyjnego wywołania metody.
using System;
namespace Metody
{
    class Program
    {
        static void Main(string[] args)
        {
            Silnia sl = new Silnia();
            Console.Write("Silnia liczby 6 to : {0}", sl.ObliczSilnie(6));
            Console.ReadKey();
            // Wynik działania programu
            // Silnia liczby 6 to : 720
    }
    class Silnia
    {
        public int ObliczSilnie(int liczba)
        {
            int wynik;
            if (liczba == 1)
                return 1;
            else
            {
                wynik = ObliczSilnie(liczba - 1) * liczba;
                return wynik;
            }
        }
    }
}

Przekazywanie parametrów do metod

Podczas wywoływania metody z parametrami najpierw te parametry należy przekazać do metody.
Poniżej trzy rodzaje parametrów, które można przekazać do metody:
  • Parametry typu wartościowego (value parameters) - sposób ten pozwala na skopiowane aktualnej wartości argumentu i przekazanie jej w formie parametru do wnętrza metody. W tym przypadku zmiany parametru dokonane wewnątrz funkcji nie wpływają na argument. Oznacza to, iż do metody przekazaliśmy jedynie kopię tej wartości stąd zmiany dokonywane na niej nie mają wpływu na zmianę parametru, który przekazaliśmy do metody;
  • Parametry typu referencyjnego (reference parameters) - sposób ten kopiuje odniesienie do parametru w postaci adresu w pamięci do wnętrza funkcji. Oznacza to, iż zmiany wprowadzone wewnątrz tej funkcji będą miały wpływ na wartość argumentu;
  • Parametry typu wyjściowego (output parameters) - metoda ta pozwala na zwrócenie więcej niż jednej wartości.

Parametry typu wartościowego

Jest to domyślny sposób przekazywania parametrów do metody. Kiedy metoda jest wywoływana, nowa komórka w pamięci jest tworzona dla każdego przekazywanego parametru.

Wartości aktualnych parametrów przekazywane są do wspomnianych wyżej komórek pamięci. W związku z tym, zmiany na parametrach wewnątrz metody nie mają wpływu na wartość argumentów przekazywanych do tej metody.
Omówmy działanie na poniższym przykładzie:
using System;
namespace MetodyTypyWartosciowe
{
    class Program
    {
        static void Main(string[] args)
        {
            OperacjeNaLiczbach onl = new OperacjeNaLiczbach();
            int a = 100;
            int b = 200;
            Console.WriteLine("Wartość a przed zamianą: {0}", a);
            Console.WriteLine("Wartość b przed zamianą: {0}", b);
            // Wywołanie metody odwracającej kolejność
            onl.ZamienKolejnosc(a, b);
            Console.WriteLine("Wartość a po zmianie: {0}", a);
            Console.WriteLine("Wartość b po zmianie: {0}", b);
            Console.ReadKey();
            // Wynik działania programu
            //Wartosc a przed zamiana: 100
            //Wartosc b przed zamiana: 200
            //Wartosc a po zmianie: 100
            //Wartosc b po zmianie: 200
        }
    }
    class OperacjeNaLiczbach
    {
        public void ZamienKolejnosc(int x, int y)
        {
            int tymczasowa;
            tymczasowa = x; // przypisanie wartości zmiennej x
            x = y;  // przypisanie wartości y w miejsce zmiennej x
            y = tymczasowa; // przypisanie wartośći zmiennej x do zmiennej y
        }
    }
}
Jak widać na powyższym przykładzie zmiany wartości wewnątrz metody nie mają żadnego wpływu na wartości przekazane do metody.

Parametry typu referencyjnego

Parametr referencyjny to referencja (odniesienie) do adresu w pamięci wskazanego parametru. W momencie przekazywania parametru przez referencje, w odróżnieniu od typu wartościowego, nie jest tworzona nowa komórka w pamięci. Parametr referencyjny ma dokładnie to samo odniesienie do miejsca w pamięci do aktualnie używany parameter.

Parametr referencyjny jest definiowany przez użycie słowa kluczowego ref.
Omówmy działanie na poniższym przykładzie:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MetodyTypReferencyjny
{
    class Program
    {
        static void Main(string[] args)
        {
            OperacjeNaLiczbach onl = new OperacjeNaLiczbach();
            int a = 100;
            int b = 200;
            Console.WriteLine("Wartość a przed zamianą: {0}", a);
            Console.WriteLine("Wartość b przed zamianą: {0}", b);
            // Wywołanie metody odwracającej kolejność
            onl.ZamienKolejnosc(ref a, ref b);
            Console.WriteLine("Wartość a po zmianie: {0}", a);
            Console.WriteLine("Wartość b po zmianie: {0}", b);
            Console.ReadKey();
            // Wynik działania programu
            //Wartosc a przed zamiana: 100
            //Wartosc b przed zamiana: 200
            //Wartosc a po zmianie: 200
            //Wartosc b po zmianie: 100
        }
    }
    class OperacjeNaLiczbach
    {
        public void ZamienKolejnosc(ref int x, ref int y)
        {
            int tymczasowa;
            tymczasowa = x; // przypisanie wartości zmiennej x
            x = y;  // przypisanie wartości y w miejsce zmiennej x
            y = tymczasowa; // przypisanie wartośći zmiennej x do zmiennej y
        }
    }
}
Powyższy przykład pokazuje, że zmiany wartości wewnątrz metody mają pływ na zmienne przekazne, jako parametry typu referencyjnego do takiej metody.

Parametry typu wyjściowego

Instrukcja return powala na zwrócenie tylko jednej wartości z metody. Jednakże, za pomocą parametrów wyjściowych, można zwrócić większą liczbę takich wartości. Parametry wyjściowe podobne są do typów referencyjnych, z tą różnicą, że pierwsze z nich zwracają dane z metody, podczas gdy te drugie te dane przekazują do metody.

Parametr wyjściowy jest definiowany przez użycie słowa kluczowego out.
Omówmy działanie na poniższym przykładzie:
using System;
namespace MetodyTypyWyjsciowe
{
    class Program
    {
        static void Main(string[] args)
        {
            OperacjeNaLiczbach onl = new OperacjeNaLiczbach();
            int a = 150;
            Console.WriteLine("Liczba przed wywołaniem metody: {0}", a);
            // Wywołanie metody
            onl.PobierzWartosc(out a);
            Console.WriteLine("Liczba po wywołaniu metody: {0}", a);
            Console.ReadKey();
            // Wynik działania programu
            //Liczba przed wywolaniem metody: 150
            //Liczba po wywolaniu metody: 5
        }
    }
    class OperacjeNaLiczbach
    {
        public void PobierzWartosc(out int x)
        {
            int tymczasowa = 5;
            x = tymczasowa;
        }
    }
}
Warto pamiętać, że zmienna, która będzie zwracana nie musi mieć przypisanej wartości. Parametry wyjściowe są szczególnie przydatne kiedy musimy zwrócić z metody parametry bez przypisywania im początkowej wartości. Poniższy przykład pozwoli łatwiej to zrozumieć:
using System;
namespace MetodyTypyWyjsciowe
{
    class Program
    {
        static void Main(string[] args)
        {
            OperacjeNaLiczbach onl = new OperacjeNaLiczbach();
            // Definicja zmiennych lokalnych
            int a, b;
            // wywołanie metody zwracającej parametry
            onl.PobierzWartosci(out a, out b);
            Console.WriteLine("Wartość liczby a po wywołaniu metody: {0}", a);
            Console.WriteLine("Wartość liczby b po wywołaniu metody: {0}", b);
            Console.ReadLine();
        }
    }
    class OperacjeNaLiczbach
    {
        public void PobierzWartosci(out int x, out int y)
        {
            Console.WriteLine("Podaj pierwszą wartość: ");
            x = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Podaj drugą wartość: ");
            y = Convert.ToInt32(Console.ReadLine());
        }
    }
}