Dela via


Implicit inskrivna lokala variabler (C#-programmeringsguide)

Lokala variabler kan deklareras utan att ange en explicit typ. Nyckelordet var instruerar kompilatorn att härleda typen av variabel från uttrycket till höger om initieringsinitieringssatsen. Den härledda typen kan vara en inbyggd typ, en anonym typ, en användardefinierad typ eller en typ som definierats i .NET-klassbiblioteket. Mer information om hur du initierar matriser med varfinns i Implicit typade matriser.

I följande exempel visas olika sätt på vilka lokala variabler kan deklareras med 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>();

Det är viktigt att förstå att nyckelordet var inte betyder "variant" och inte anger att variabeln är löst skriven eller senbunden. Det innebär bara att kompilatorn bestämmer och tilldelar den lämpligaste typen.

Nyckelordet var kan användas i följande kontexter:

  • På lokala variabler (variabler som deklarerats i metodomfånget) som du ser i föregående exempel.

  • I en för initieringsinitieringssats.

    for (var x = 1; x < 10; x++)
    
  • I en foreach-initieringsinitieringssats .

    foreach (var item in list) {...}
    
  • I en using-instruktion .

    using (var file = new StreamReader("C:\\myfile.txt")) {...}
    

Mer information finns i Använda implicit inskrivna lokala variabler och matriser i ett frågeuttryck.

var- och anonyma typer

I många fall är användningen av var valfri och är bara en syntaktisk bekvämlighet. Men när en variabel initieras med en anonym typ måste du deklarera variabeln som var om du behöver komma åt objektets egenskaper vid ett senare tillfälle. Det här är ett vanligt scenario i LINQ-frågeuttryck. Mer information finns i Anonyma typer.

Från källkodens perspektiv har en anonym typ inget namn. Om en frågevariabel har initierats med varär det enda sättet att komma åt egenskaperna i den returnerade sekvensen av objekt att använda var som typ av iterationsvariabel i -instruktionen foreach .

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
 */

Kommentarer

Följande begränsningar gäller för implicit skrivna variabeldeklarationer:

  • var kan endast användas när en lokal variabel deklareras och initieras i samma instruktion. Variabeln kan inte initieras till null eller till en metodgrupp eller en anonym funktion.

  • var kan inte användas på fält i klassomfånget.

  • Variabler som deklareras med hjälp var av kan inte användas i initieringsuttrycket. Det här uttrycket är med andra ord lagligt: int i = (i = 20); men det här uttrycket skapar ett kompileringsfel: var i = (i = 20);

  • Flera implicit inskrivna variabler kan inte initieras i samma instruktion.

  • Om en typ med namnet var finns i omfånget matchas nyckelordet var till det typnamnet och behandlas inte som en del av en implicit skriven lokal variabeldeklaration.

Implicit inmatning med nyckelordet var kan endast tillämpas på variabler i det lokala metodomfånget. Implicit skrivning är inte tillgängligt för klassfält eftersom C#-kompilatorn skulle stöta på en logisk paradox när koden bearbetades: kompilatorn måste känna till typen av fält, men den kan inte fastställa typen förrän tilldelningsuttrycket har analyserats och uttrycket kan inte utvärderas utan att känna till typen. Ta följande kod som exempel:

private var bookTitles;

bookTitles är ett klassfält givet typen var. Eftersom fältet inte har något uttryck att utvärdera är det omöjligt för kompilatorn att härleda vilken typ bookTitles som ska vara. Dessutom är det inte heller tillräckligt att lägga till ett uttryck i fältet (som för en lokal variabel):

private var bookTitles = new List<string>();

När kompilatorn stöter på fält under kodkompilering registrerar den varje fälttyp innan de uttryck som är associerade med den bearbetas. Kompilatorn stöter på samma paradox som försöker parsa bookTitles: den måste känna till typen av fält, men kompilatorn skulle normalt fastställa vartypen genom att analysera uttrycket, vilket inte är möjligt utan att känna till typen i förväg.

Du kanske upptäcker att det var också kan vara användbart med frågeuttryck där den exakta konstruerade typen av frågevariabeln är svår att avgöra. Detta kan inträffa med grupperings- och beställningsåtgärder.

Nyckelordet var kan också vara användbart när den specifika typen av variabel är omständlig att skriva på tangentbordet, eller är uppenbar eller inte lägger till kodens läsbarhet. Ett exempel där var är användbart på det här sättet är med kapslade generiska typer som de som används med gruppåtgärder. I följande fråga är IEnumerable<IGrouping<string, Student>>typen av frågevariabel . Så länge du och andra som måste behålla din kod förstår detta, är det inga problem med att använda implicita skrivningar för enkelhetens skull och korthet.

// 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;

Användningen av var hjälper till att förenkla din kod, men dess användning bör begränsas till fall där den krävs, eller när den gör koden enklare att läsa. Mer information om när du ska använda var korrekt finns i avsnittet Implicit inskrivna lokala variabler i artikeln C#-kodningsriktlinjer.

Se även