Velmi často se setkávám s tím, že .NET vývojáři mluví o jedné věci, ale mají na mysli jinou, což bývá matoucí. Není to jen výsadou překladu z angličtiny do češtiny, setkávám se s tím i v anglicky komunikující komunitě. Rozdíly mezi výrazy nejsou propastné a v rámci konverzace, článku nebo jiné komunikace se většinou doberete k tomu, co má autor opravdu na mysli. Nicméně, můj názor je, že alespoň ten, kdo vzdělává ostatní, neměl by takové rozdíly opomínat a šířit tak neznalost na další. V tomto článku se na některé rozdíly zaměřím a budu přidávat nové, jakmile se s nimi setkám. Abych také podpořil moje vysvětlení, přidám vždy odkaz na specifikaci (C# 5.0).
Parametr vs argument
Pravděpodobně nejčastější nepochopení, se kterým se setkávám. Vysvětlím na příkladu.
void Print(string text)
{
if (string.IsNullOrEmpty(text))
throw new ArgumentNullException(text);
Console.WriteLine(text);
}
Print("sample argument");
Toto je definice metody Print, která má jediný parametr typu string. Uvnitř metody nejdříve provádím kontrolu správnosti argumentu text a poté jej vytisknu. Doufám, že rozdíl je patrný. Když mám na mysli signaturu metody, je pro mě text její součástí (ačkoliv je to pouze typ této proměnné, ne název) a mluvím o něm jako o parametru. Když mám na mysli hodnotu tohoto parametru, ať už v rámci volání metody nebo v rámci kontroly správnosti uvnitř metody, mluvím o něm jako o argumentu. (Viz spec §1.6.6.1).
Implicitní vs explicitní
Často se této kategorizaci můžete úplně vyhnout, ale v případech, kdy to nejde, je dobré vědět rozdíl. Opět vysvětlím na příkladu.
int a = 1;
long b = a;
Druhý řádek kódu se dá správně popsat jako implicitní numerická konverze. Pokud prohodíte typy proměnných, pak dostanete kompilační chybu: Cannot implicitly convert type 'long' to 'int'. An explicit conversion exists (are you missing a cast?). V překladu: Nelze implicitně zkonvertovat long na int. Existuje explicitní konverze (nechybí vám přetypování?). To znamená, že kompilátor neví, jak přesně by měl z long udělat int, protože může dojít ke ztrátě informace. Proto je potřeba explicitně uvést, že o tom víte, jako v následujícím kousku kódu.
long a = 1;
int b = (int) a;
Tato kategorizace se v .NET rozlišuje nejvíce v případech konverze, kde její opomenutí může změnit chování kódu (C# kompilátor to naštěstí hlídá). Kromě toho se s ní také můžete setkat u klíčového slova var, které se používá pro implicitní typování lokálních proměnných. (Viz spec §6.1 a §6.2).
Třída vs typ
.NET rozlišuje několik typů proměnných, kde třída (class) je jeden z nich. Kompletní tabulku rozdělení najdete v specifikaci §1.3, jako příklad ale uvedu ještě strukturu (struct) nebo delegát. Je tedy vhodné mít toto na mysli, a pokud tvrdím, že někam mohu vložit instanci jakékoliv třídy, zamyslet se nad tím, jestli tam náhodou nemohu vložit také instanci jiného typu. S tímto se nejčastěji setkávám u autorů článků a blogů a není to žádné závažné provinění, ale proč se omezovat jen na třídy, když je typový systém .NET tak bohatý?
Funkce vs metoda
Princip funkce je známý například z jazyka C nebo dynamických jazyků jako je Ruby, kde funkce je samostatná entita identifikovaná jménem, která může (ale nemusí) přijímat parametry a vracet výsledek. V .NET funkce jako takové nejsou, namísto toho se rozlišuje několik druhů tzv. function members, což jsou členy typu (všimněte si záměrného použití výrazu typ namísto třída) nebo objektu, které obsahují spustitelný kód (viz spec §1.6.7). Mezi ně patří metoda, konstruktor, property, indexer, event, operátor a destruktor (viz spec nebo MSDN). Všechny druhy jsou také identifikovány jménem, ale kromě toho je nutno znát i jméno objektu, na kterém jsou definovány. Je tedy v pořádku nazvat metodu funkcí, ale pokud máte na mysli metodu, je lepší o ní mluvit jako o metodě, než jako o funkci, protože pod funkcí si lze představit něco jiného.
Víte o nějakém dalším případu, který by zde neměl chybět?