Tajemný modifikátor out v C#

Minisérie odhalování tajů jazyka C# pokračuje. Po minulém zjištění, co vlastně dělá záhadný zavináč, následuje modifikátor parametrů metod – out.

Použití

Běžné je, že metody jsou izolované od okolního programu a nemění přímo hodnotu proměnných, které jsou jim předány coby parametry (vytvářejí si lokální kopie, s kterými pracují). Modifikátor out, stejně jako jeho kolega ref, toto mění a dá se použít, pokud chceme z metody vrátit více hodnot najednou.

Na rozdíl od ref ovšem nemusí být proměnné před předáním metodě inicializovány (tedy nemusí mít přiřazenou hodnotu) a jsou-li, uvnitř metody se to nijak neprojeví. Podívejme se na primitivní příklad:

class Program {
	static void Main(string[] args) {
		const int c = 4; // inicializace čísla, s kterým budeme počítat
		int m; // proměnná pro uložení jednoho výsledku - bez výchozí hodnoty
		double o; // proměnná pro uložení druhého výsledku - bez výchozí hodnoty

		Pocty(c, out m, out o); // provedení výpočtu - výsledky uloženy do m a o
		Console.WriteLine("{0} -> {1}, {2}", c, m, o);
	}

	static void Pocty(int cislo, out int mocnina, out double odmocnina) {
		mocnina = cislo * cislo;
		odmocnina = Math.Sqrt(cislo);
	}
}

Metoda Pocty má v signatuře jeden klasický parametr (cislo) a dva s přidaným modifikátorem out (mocnina, odmocnina). Návratový typ je void, takže v těle chybí i return, k „vrácení“ hodnot se využije pozměnění předaných parametrů.

V metodě Main je definována konstanta představující číslo, na kterém se budou provádět výpočty, a dvě proměnné bez inicializace výchozí hodnoty. Tyto tři prvky pak předáme metodě Pocty a nesmíme při tom zapomenout opět uvést klíčové slovo out.

Jakmile program opustí Pocty, bude v proměnné m druhá mocnina čísla c, v proměnné o bude jeho druhá odmocnina a výsledkem bude výpis:

4 -> 16, 2

Při použití ref je možné s hodnotou proměnné pracovat jakkoliv – metoda, které je předána, ji může používat k dalším výpočtům nebo upravovat. U out toto neplatí – dá se použít pouze k získávání hodnoty z metody. Pokud bychom na začátku inicializovali např. m na 6, tak uvnitř Pocty tato hodnota nebude přístupná, dokud ji nenastavíme přímo v metodě. Jakmile se tak ale stane, přetrvává i mimo ni.

static void Main(string[] args) {
	const int c = 4;
	int m = 6; // inicializujeme i "m"
	double o;

	Pocty(c, out m, out o);
	// "m" má hodnotu, kterou dostala v metodě, bez ohledu na inicializaci
	Console.WriteLine("{0} -> {1}, {2}", c, m, o);
}

static void Pocty(int cislo, out int mocnina, out double odmocnina) {
	// tady je "mocnina" unassigned
	mocnina = cislo * cislo;
	// a teď už má hodnotu
	odmocnina = Math.Sqrt(cislo);
	// a nyní získala hodnotu i "odmocnina"
}

Omezení

Než  metoda s modifikátorem parametru out skončí, daná proměnná musí mít nastavenou nějakou hodnotu. Pokud bychom v příkladu nahoře vynechali řádek s výpočtem mocniny nebo odmocniny, překladač by okamžitě zahlásil chybu.

Vlastnosti objektů se neberou jako proměnné a nelze je tímto způsobem předat.

Z hlediska signatur se považují jako totožné metody, které se liší pouze parametry ref a out, a nelze je tedy takto přetěžovat. Příklad napoví více. První metoda je výchozí, zápis druhé je nedovolené přetížení a teprve třetí je v pořádku.

static void Pocty(int cislo, out int mocnina, out double odmocnina); // první metoda
static void Pocty(int cislo, ref int mocnina, out double odmocnina); // nelze
static void Pocty(int cislo, int mocnina, out double odmocnina); // v pořádku

Závěr

Tolik tedy další ze zákoutí jazyka C#. Na závěr podotýkám, že klíčové slovo out má ještě jeden význam, a to v generických rozhraních a delegátech. Jeho protějškem je pak modifikátor in.

Klasický odkaz na oficiální dokumentaci na MSDN: http://msdn.microsoft.com/en-us/library/ee332485.aspx.

2 thoughts on “Tajemný modifikátor out v C#

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *