MetodyCzęść NR.4W poprzednim wpisie pokazałem jak łatwo i szybko napisać prostą aplikacje graficzną.
Metoda C#
Jednak jak podkreśliłem w poprzednim wpisie, znajomość operacji arytmetycznych to za mało do budowania nawet takich małych programików.

Dzisiaj pokażę jak tworzyć własne metody. Jest to jeden z najprostszych trików do podzielenia kodu na mniejsze części, tak by stał się on bardziej czytelny.

Szkielet metody

Składnia tworzenia metody jest następująca:

typ_zwracany nazwa_metody (lista parametrów)
{
    //blok kodu który wykona się przy metodzie 
}

typ_zwracany: tutaj określamy typ zwracany przez metodę. Typ, czyli przykładowo “int”, “string” i tak dalej. Jeśli metoda ma nie zwracać żadnej wartości korzystamy ze słowa kluczowego void.

nazwa_metody: Samo wyjaśnienie . Obowiązują tu te same zasady co do nazewnictwa zmiennych.

lista parametrów:Metoda nie musi koniecznie jej posiadać. Lista parametrów zawiera w sumie informacje, jakie zmienne muszą być przesłane do metody by wykonać daną operacje. Te parametry istnieją wewnątrz metody. Każdy parametr musi być oddzielony przecinkiem.

//blok kodu:Kod, który się wykona przy wywoływaniu metody. Jeśli metoda musi zwracać wartość to w tym bloku powinno być zawarte słowo kluczowe return wraz z daną zwracaną.

C# nie wspiera metod globalnych w przeciwieństwie do C i C++. Metody muszą być zadeklarowane wewnątrz klas.

Oto przykład metody odejmującej, która zwraca wynik działania bazując na podanych dwóch zmiennych.

int Odejmowanie(int x1,int x2)
{
    return x1 - x2;
}

W przykładzie metoda nie zwraca żadnej wartość, ale wyświetla wynik działania za pomocą MessageBox.

void Odjemowanie(int x1,int x2)
{
    MessageBox.Show((x1 - x2).ToString());
}

Małe wyjaśnienie słowa kluczowego return. W metodzie zwracające, jeśli zmienna została już zwrócona reszta kodu się nie wykona.

string Zwracam()
{
    return "LOL";
    string s = "Do tego program nigdy nie dojdzie";
}

Teraz gdy wiesz jak napisać metodę. Zobaczymy jak ją wywołać.

Wywoływanie metody

Wywoływanie metody wygląda w ten sposób.

WykonamOperacje();
int rezultat = ObliczeCos(1,2);

Aby wywołać metodę trzeba pamiętać o następujących zasadach:

  • Musisz podać odpowiednią listę argumentów, jaką metoda potrzebuje.
  • Argumenty muszą być tego samego typu, jakiego są potrzebne do metody.
  • Musisz odwołać się do niej poprzez dokładną jej nazwę.Wielkość liter ma znaczenie
  • Pamiętaj czy metoda zwraca wartość. Jeśli zwraca wartość, to trzeba ją przechwycić poprzez zmienne pomocnicze.
  • Nawet jeśli metoda nie ma żadnej listy argumentów to i tak trzeba napisać () by ją wywołać.

Aby wszystko było jasne oto przykłady:

void MessageNumber(string komunikat,int liczba)
{
    MessageBox.Show(komunikat +" : " +liczba.ToString());
}

…oraz użycie tej metody.

MessageNumber(); //Za mało argumentów 
MessageNumber("Liczba x")//Brakuje argumentu 
MessageNumber(1, 2); //Zły typ argumentu
MessageNumber(5,"Cos");//Zła kolejność 
MessageNumber("Liczba",1212);//Poprawne użycie

Wypadałoby wspomnieć o różnicy pomiędzy użyciem metody w programie Konsolowym , a WPF.

Statyczna metoda VS Niestatyczna metoda

Zanim jednak spróbujesz użyć metod w aplikacji konsolowej bądź WPF wypadałoby wspomnieć o drobnej różnicy przy ich w używaniu.

W konsolowej aplikacji metody wewnątrz klasy "Program" muszą być statyczne, by można było ich użyć wewnątrz metody “Main”. Wynika to z tego , że w aplikacji konsolowej nasze akcje są wyświetlana za pomocą metody Main, która jest statyczna. Wewnątrz statycznej metody można wywołać tylko kolejną statyczną metodę.

namespace ConsoleApplication2
{
    class Program {
        static void Main(string[] args)
        {
            int a = Mnozenie(2, 3);
            Console.WriteLine(a);
            Console.ReadKey();
        }
        static int Mnozenie(int x1, int x2)
        {
            return x1 * x2;
        }
    }
}

Metoda napisana w aplikacji WPF nie musi być statyczna. W tym przykładzie metoda uruchomi się jeszcze przed zobaczeniem okna głównego aplikacji, ponieważ kod jej wywołania jest w konstruktorze klasy MainWindow.

namespace WpfApplication1
{
    public partial class MainWindow : Window {
        public MainWindow()
        {
            InitializeComponent();
            Odjemowanie(2, 3);
        }

        void Odjemowanie(int x1,int x2)
        {
            MessageBox.Show((x1 - x2).ToString());
        }
    }
}

Jaka jest różnica pomiędzy metodą statyczną  a metodą niestatyczną? Aby to zobrazować musiałbym wyjaśnić, czym jest klasa i w jakich wypadkach może mieć ona metodę statyczną , a kiedy zwyczajną. Na razie nie będzie to jednak potrzebne.

Przeciążanie metod

Jak wcześniej zaznaczyłem metoda “Console.Wrtiteline()” jest metodą przeciążoną i ma aż 19 wersji z różnymi parametrami. Dzięki temu ta metoda może wyświetlić nam w konsoli parametry liczbowe albo nawet logiczne. Czyli robi dokładnie to samo, mimo iż podaje do niej inne parametry.

bool t = true;
int l = 121;
Console.WriteLine(t);
Console.WriteLine(l);

Jak stworzyć przeciążoną metodę. Jeśli dwa identyfikatory mają takie same nazwy stają się one przeciążone. Normalnie, gdy zadeklarujemy dwie zmienne o te samej nazwie, kompilator zgłosi nam błąd. Jednak dla metody o tej samej nazwie, ale z różnymi parametrami już nie.

Pisząc dwie wersje metody z różną listą parametrów tworzymy dwie możliwości ich użycia.
Jak widać na obrazku metoda “Mnozenie()” jest w dwóch wersjach. W jednej potrzebuje 2 parametrów w drugiej aż 3.
Przeciązanie metod

Nie ma tutaj dużej filozofii w ten sposób mogę utworzyć tyle wersji ile potrzebę.

Metody z opcjonalnymi parametrami

Właśnie zobaczyłeś jak działa przeciążanie metod. Kiedy aplikacja się skompiluje kompilator będzie wiedział z jakiej wersji skorzystać, bazując na podanych w metodzie parametrach.

Istnieje jeszcze jednak inny mechanizm przy tworzeniu metod. W niektórych sytuacjach jest on bardziej użyteczny niż przeciążanie metod. Polega to na utworzeniu metody z opcjonalnymi parametrami. Zalety takiego rozwiązania łatwo wykazać za pomocą prezentacji.

Załóżmy , że mam metodę dwa razy przeciążoną . Operacja wykonywana w metodzie “PracaPraca” , powiedzmy , że zapisuje liczbę dni, godzin i minut do źródła danych.

void PracaPraca(int liczbaDni,int liczbaGodzin,int liczbaMinut)
{ }

void PracaPraca(int liczbaGodzin, int liczbaMinut)
{ }

Jak na razie nie ma tu żadnego problemu. Ale co się stanie, jeśli zechcę stworzyć metody dwa razy przeciążone, które pobierają tylko jeden parametr np. w jedna wersji metoda będzie potrzebowała tylko liczbę dni , a w drugiej tylko liczbę godzin.

void PracaPraca(int liczbaDni)
{ }

void PracaPraca(int liczbaGodzin)
{ }

Kompilator w takim wypadku zgłosi błąd.

Błąd metoda przeciążona

Taki kod nie przejdzie przez kompilator z prostego powodu. Kompilator i program nie wie, z której metody będziesz korzystał, jeśli obie potrzebują jednej zmiennej tego samego typu.

int liczbaDni = 2;
int liczbaGodzin = 18;
PracaPraca(liczbaDni); 
//koleś czego chcesz której metody mam użyć 
PracaPraca(liczbaGodzin);  
//koleś czego chcesz której metody mam użyć

Do takiej sytuacji mamy parametry opcjonalne. Do zrozumienia jak opcjonalne parametry działają muszę pokazać dwie rzeczy:

  • Jak można w C# zadeklarować zmienne opcjonalne.
  • Jak można w C# wywołać metodę podając parametry w innej kolejności

Deklaracja metody z opcjonalnymi parametrami

W metodzie można przypisać parametrom stałe wartości.

static void PracaPraca(int liczbaDni = 0,int liczbaGodzin = 0,
int liczbaMinut = 0)
{ }

Jedyną zasadą dotyczącą opcjonalnych parametrów jest fakt, że wszystkie zmienne, które nie mają wartości domyślnych muszą być najpierw zadeklarowane.

Błąd kolejność parametrów
Visual Studio zaznacza , że parametry mają domyśle wartości.

Metoda z opcjonalnymi parametrami
Jednak zapewne zauważyłeś, że istnieje problem z umieszczaniem właściwej kolejności parametrów. Jak można podać tylko liczbę godzin?.

Inna kolejność parametrów

Domyślnie w C# kolejność parametrów musi być podawana od lewej do prawej . Jednak da się to rozwiązać poprzez odwołanie się do nich za pomocą ich nazw.

PracaPraca(liczbaGodzin: 18);
PracaPraca(liczbaMinut:45,liczbaDni:1)

Nawet Visual Studio pomaga w tym procesie ,więc nie musisz pamiętać nazw zmiennych do metody.

Po nazwach zmienny w metodzie

Prawda , że to proste.

Skomplikujmy jednak teraz sprawę i stwórzmy metodę dwa razy przeciążoną z parametrami opcjonalnymi i nieopcjonalnymi.

Łączenie metody przeciążonej z parametrami opcjonalnymi. Problemy z kompilacją?

Metoda przeciążona z różnymi typami parametrów wygląda następująco.

static void PracaPraca(bool zadanieWykonane,
int liczbaDni = 0,int liczbaGodzin = 0)
{ }

static void PracaPraca(bool zadanieWykonane, 
int liczbaDni = 0, int liczbaGodzin = 0, int liczbaMinut = 0)
{ }

Łącząc technikę przeciążania metod z parametrami opcjonalnymi wymaga przestrzegania pewnych zasadach. Spójrzmy na poniższy kod.

PracaPraca(true, 1, 8);//pierwsza wersja 
PracaPraca(true,liczbaMinut:12);//druga wersja 
PracaPraca(true, 2);//wywołuje błąd 

PracaPraca(true, liczbaGodzin: 12);
//tutaj też kompilator nie wie z której wersji skorzystać 
PracaPraca(true);//to samo 

Z pierwszym zapisem kompilator nie ma problemów, ponieważ wszystkie parametry potrzebne do wersji pierwszej zostały podane.

Z drugim zapisem kompilator też nie ma problemów, ponieważ wie ,że zmienna reprezentująca liczbę minut istnieje tylko w drugiej wersji.

Z trzecim zapisem kompilator ma już problem, mając podany parametr - liczbę dni, nie jest on w stanie stwierdzić, z której wersji ma skorzystać, ponieważ obie wersje mają ten sam parametr opcjonalny. Podobny problem występuje w zapisie 4, jak i 5.

W następnym odcinku

Opisze warunki if oraz wyrażenia logiczne w C#.