Implicitně zadané místní proměnné (Průvodce programováním v C#)
Místní proměnné lze deklarovat bez explicitního typu. Klíčové var
slovo dává kompilátoru pokyn, aby odvodil typ proměnné z výrazu na pravé straně inicializačního příkazu. Odvozený typ může být integrovaný typ, anonymní typ, uživatelem definovaný typ nebo typ definovaný v knihovně tříd .NET. Další informace o tom, jak inicializovat pole pomocí var
, naleznete v tématu Implicitně typovaná pole.
Následující příklady ukazují různé způsoby, kterými lze deklarovat místní proměnné:var
// i is compiled as an int
var i = 5;
// s is compiled as a string
var s = "Hello";
// a is compiled as int[]
var a = new[] { 0, 1, 2 };
// expr is compiled as IEnumerable<Customer>
// or perhaps IQueryable<Customer>
var expr =
from c in customers
where c.City == "London"
select c;
// anon is compiled as an anonymous type
var anon = new { Name = "Terry", Age = 34 };
// list is compiled as List<int>
var list = new List<int>();
Je důležité pochopit, že klíčové slovo neznamená "variantu" a neznamená, že var
proměnná je volně zadaná nebo opožděná. Jenom to znamená, že kompilátor určí a přiřadí nejvhodnější typ.
Klíčové var
slovo lze použít v následujících kontextech:
V místních proměnných (proměnné deklarované v oboru metody), jak je znázorněno v předchozím příkladu.
V příkazu inicializace .
for (var x = 1; x < 10; x++)
V inicializačním příkazu foreach .
foreach (var item in list) {...}
-
using (var file = new StreamReader("C:\\myfile.txt")) {...}
Další informace naleznete v tématu Použití implicitně zadaných místních proměnných a polí ve výrazu dotazu.
var a anonymní typy
V mnoha případech je použití var
volitelné a je to jen syntaktické pohodlí. Pokud je však proměnná inicializována anonymním typem, musíte tuto proměnnou deklarovat, jako var
kdybyste potřebovali přístup k vlastnostem objektu v pozdějším bodě. Toto je běžný scénář ve výrazech dotazu LINQ. Další informace naleznete v tématu Anonymní typy.
Z pohledu zdrojového kódu nemá anonymní typ žádný název. Proto pokud byla proměnná dotazu inicializována pomocí var
, pak jediný způsob, jak získat přístup k vlastnostem ve vrácené sekvenci objektů, je použít var
jako typ iterační proměnné v foreach
příkazu.
class ImplicitlyTypedLocals2
{
static void Main()
{
string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
// If a query produces a sequence of anonymous types,
// then use var in the foreach statement to access the properties.
var upperLowerWords =
from w in words
select new { Upper = w.ToUpper(), Lower = w.ToLower() };
// Execute the query
foreach (var ul in upperLowerWords)
{
Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
}
}
}
/* Outputs:
Uppercase: APPLE, Lowercase: apple
Uppercase: BLUEBERRY, Lowercase: blueberry
Uppercase: CHERRY, Lowercase: cherry
*/
Poznámky
Následující omezení platí pro implicitně typované deklarace proměnných:
var
lze použít pouze v případech, kdy je místní proměnná deklarována a inicializována ve stejném příkazu; proměnnou nelze inicializovat na hodnotu null nebo do skupiny metod nebo anonymní funkce.var
nelze použít u polí v oboru třídy.Proměnné deklarované pomocí použití
var
nelze použít ve výrazu inicializace. Jinými slovy, tento výraz je právní:int i = (i = 20);
ale tento výraz vytváří chybu v době kompilace:var i = (i = 20);
Ve stejném příkazu nelze inicializovat více implicitně zadaných proměnných.
Pokud je název
var
typu v oboru,var
klíčové slovo se přeloží na tento název typu a nebude považováno za součást implicitně zadané deklarace místní proměnné.
Implicitní psaní pomocí klíčového var
slova lze použít pouze u proměnných v oboru místní metody. Implicitní psaní není k dispozici pro pole tříd, protože kompilátor jazyka C# by při zpracování kódu narazil na logický paradox: kompilátor potřebuje znát typ pole, ale nemůže určit typ, dokud se výraz přiřazení neanalyzuje, a výraz nelze vyhodnotit, aniž by věděl typ. Uvažujte následující kód:
private var bookTitles;
bookTitles
je pole třídy s daným typem var
. Protože pole nemá žádný výraz k vyhodnocení, není možné kompilátor odvodit, jaký typ bookTitles
má být. Přidání výrazu do pole (stejně jako u místní proměnné) navíc není dostatečné:
private var bookTitles = new List<string>();
Když kompilátor během kompilace kódu narazí na pole, zaznamenává každý typ pole před zpracováním všech výrazů přidružených k němu. Kompilátor narazí na stejný paradox, který se snaží analyzovat bookTitles
: potřebuje znát typ pole, ale kompilátor obvykle určí var
typ výrazu analýzou výrazu, což není možné, aniž by předem věděl typ.
Můžete také zjistit, že var
může být užitečné u výrazů dotazu, ve kterých je obtížné určit přesný vytvořený typ proměnné dotazu. K tomu může dojít u operací seskupování a řazení.
Klíčové var
slovo může být užitečné také v případě, že určitý typ proměnné je zdlouhavý psát na klávesnici, nebo je zřejmé, nebo nepřidá k čitelnosti kódu. Jedním z příkladů, kde var
je tento způsob užitečný, je s vnořenými obecnými typy, jako jsou ty, které se používají s operacemi skupiny. V následujícím dotazu je IEnumerable<IGrouping<string, Student>>
typ proměnné dotazu . Pokud to vy i ostatní, kteří si musí zachovat kód, není problém s používáním implicitního psaní pro pohodlí a stručnost.
// Same as previous example except we use the entire last name as a key.
// Query variable is an IEnumerable<IGrouping<string, Student>>
var studentQuery3 =
from student in students
group student by student.Last;
Použití var
pomáhá zjednodušit kód, ale jeho použití by mělo být omezeno na případy, kdy je požadováno, nebo když usnadňuje čtení kódu. Další informace o tom, kdy se má správně používat var
, najdete v části Implicitně zadané místní proměnné v článku Pokyny pro kódování jazyka C#.