Poznáváme C# a Microsoft .NET 24. díl – speciální případy metod

Dnešní díl bych rád věnoval seznámení s použitím a deklarací speciálních případů metod. Mezi takovéto druhy metod, které zatím nebyly v tomto seriálu představeny se řadí metody s proměnným počtem parametrů a metody, u jejichž parametrů je uveden modifikátor ref nebo out.

Metody s proměnným počtem parametrů

Někdy se může stát, že potřebujeme definovat metodu, u které chceme nechat počet jejích parametrů variabilní. K tomu, abychom tohoto cíle dosáhli nám jazyk C# nabízí k použití modifikátor params. Tento modifikátor, který je povoleno uvést pouze před posledním vstupním parametrem metody.

Za tímto modifikátorem vstupního parametru se uvádí jako typ parametru pole určitého typu, který představuje typ vstupních parametrů o variabilním počtu. Z tohoto důvodu je pak v těle metody možné ony parametry získávat normální iterací pole. V deklaraci metody je povolen pouze jeden tento modifikátor. Následující ukázková třída Scitac, demonstruje použití modifikátoru params.

/// <summary>
/// Ukazka na pouziti metod s promennym poctem parametru
/// </summary>
public class Scitac
{
 public static int Secti(int a, int b)
 {
  return a + b;
 }

 //do teto metody muze vstoupit promenny pocet
 //parametru typu int.
 public static int Secti(params int[] Cisla)
 {
  int lSuma = 0;
  for(int i = 0; i < Cisla.Length; i++)
  {
   lSuma += Cisla[i];
  }
  return lSuma;
 }
}

První verze metody Secti očekává standardně dva parametry a vrátí jejich součet na tom není nic nového. Ale druhá přetížená verze této metody již používá onen „kouzelný“ modifikátor params, který zařídí to, že uživatel naší třídy bude moci metodě Secti předat libovolný počet hodnot typu int, tak jak ukazuje následující zdrojový kód.

public class ScitacTest
{
 public static void Test()
 {
  Console.WriteLine(Scitac.Secti(5,6));
  //pouziti verze metody s promennym poctem parametru
  Console.WriteLine(Scitac.Secti(1,2,3,4,5));
 }
}

V případě, že předaný počet parametrů metodě při jejím volání se přesně shoduje s nějakou deklarovanou verzí metody, je zavolána tato verze, pokud ovšem kompilátor nenalezne žádnou takovou verzi metody, která očekává tento přesný počet parametrů, použije verzi metody s modifikátorem params, samozřejmě pokud nějaká takováto verze metody existuje. Takže konkrétně v našem ukázkovém příkladě se při prvním zavoláním metody Secti použije verze deklarovaná právě pro dva vstupní parametry a při druhém volání metody, kdy jí je předáno parametrů pět, kompilátor nenalezne v definici třídy Scitac žádnou takovou verzi metody Secti, která by očekávala pět vstupních parametrů a zkusí najít nějakou verzi metody, kde se vyskytuje modifikátor params a pokud ji nalezne, tak ji použije.

Modifikátor ref

S velkou pravděpodobností se někdy při svém programování v C# dostanete do situace, kdy budete chtít, aby parametr hodnotového typu byl metodě předán nikoliv zkopírováním hodnoty (předání hodnotou), ale stejně jako v případě referenčních typů, tedy aby se změna hodnoty provedená v těle metody volaného objektu projevila i všude jinde.

Pokud tedy chceme parametr hodnotového typu předat jakoby odkazem, použijeme modifikátor vstupního parametru metody ref. Po použití tohoto modifikátoru bude parametr metody reflektovat na stejnou proměnnou, která byla metodě předána při jejím volání. Toho se hodí využít v případech, kdy chceme aby naše metoda vracela více než jednu hodnotu. Samozřejmě metoda s těmito parametry může mít normální návratovou hodnotu.

Pokud je v deklaraci metody uveden u nějakého parametru modifikátor ref, jsme nuceni při každém volání takovéto metody, také u předávaného parametru explicitně uvést modifikátor ref. Pokud předáváme metodě parametr s použitím modifikátoru ref, musíme předávanou proměnnou nejdříve inicializovat, jinak překlad programu skončí chybovým hlášením. V deklaraci metody je možné použít tento modifikátor i pro více než jeden vstupní parametr. Použití modifikátoru ref by mohlo vypadat například takto:

/// <summary>
/// Ukazka pouziti modifikatoru vstupniho parametru metody ref
/// </summary>
public class ScitacRef
{
 public static void Secti(int a, int b, ref int soucet)
 {
  soucet = a + b;
 }
}

Metoda Secti v tomto příkladu očekává kromě dvou hodnot pro sečtení i třetí parametr s modifikátorem ref do kterého bude uložen výsledek součtu.

public class ScitacRefTest
{
 public static void Test()
 {
  int lSoucet = 0;
  ScitacRef.Secti(5,4, ref lSoucet);
  //Bude vypsana hodnota 9
  Console.WriteLine(lSoucet);
 }
}

Jak bylo napsáno, tak i při volání metody je potřeba uvést modifikátor ref, pokud je parametr metody s tímto modifikátorem uveden v deklaraci metody. Proměnná musela být před předáním metodě inicializována a její hodnota se po zavolání metody změnila na 9.

Tím, že při deklaraci metody u nějakého parametru použijeme modifikátor ref, vytvoříme její novou verzi, jinými slovy ji přetížíme. Z toho plyne, že je možné provést něco takovéhoto:

public class RefOverloadExam
{
 public void NejakaMetoda(int Cislo)
 {
  //implementace metody
 }
 public void NejakaMetoda(ref int Cislo)
 {
  //implementace metody
 }
}

Modifikátor out

Tento modifikátor vstupního parametru je velmi podobný modifikátoru ref, ale je zde jistý rozdíl v jejich užití. Zatímco u modifikátoru ref bylo požadováno, aby proměnná předávaná jako parametr s modifikátorem ref byla nejprve inicializována, tak u modifikátoru out toto nutné není. Avšak je nutné, aby parametr s modifikátorem out byl v metodě přiřazen. Taktéž jako u modifikátoru ref, tak i u použití tohoto modifikátoru dochází k vytvoření nové přetížené verze konkrétní metody, ale nelze vytvořit přetížení na základě toho, že se v metodě místo modifikátoru ref objeví modifikátor out a naopak. Jinak řečeno to znamená, že nemůžete provést něco takovéhoto:

public class BadOverloadExam
{
 public void NejakaMetoda(ref int Cislo)
 {
  //implementace metody
 }

 public void NejakaMetoda(out int Cislo)
 {
  //implementace metody
 }
}

Zdrojové kódy k příkladům naleznete zde.

Diskuze (2) Další článek: Amazon.com prodal Korán s nápisem Smrt všem muslimům

Témata článku: , , , , , , , , , , , , , , , ,