Implizit typisierte lokale Variablen (C#-Programmierhandbuch)
Lokale Variablen können deklariert werden, ohne einen expliziten Typ anzugeben. Das var
-Schlüsselwort weist den Compiler an, den Typ der Variablen vom Ausdruck auf der rechten Seite der Initialisierungsanweisung abzuleiten. Der hergeleitete Typ ist möglicherweise ein integrierter Typ, ein anonymer Typ, ein benutzerdefinierter Typ oder ein Typ, der in der .NET-Klassenbibliothek definiert wurde. Weitere Informationen zur Initialisierung von Arrays mithilfe von var
finden Sie unter Implizit typisierte Arrays.
Die folgenden Beispiele veranschaulichen verschiedene Arten, wie Sie lokale Variablen mit var
deklarieren können:
// 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>();
Es ist von großer Bedeutung zu verstehen, dass das var
-Schlüsselwort nicht „variant“ bedeutet, und das es nicht darauf hinweist, dass die Variable schwach typisiert oder spät gebunden ist. Es bedeutet nur, dass der Compiler den angemessensten Typen bestimmt und zuweist.
Das var
-Schlüsselwort kann in folgendem Kontext verwendet werden:
Für lokale Variablen (Variablen, die im Geltungsbereich der Methode deklariert wurden), wie in vorherigem Beispiel gezeigt.
In einer for-Initialisierungsanweisung.
for (var x = 1; x < 10; x++)
In einer foreach-Initialisierungsanweisung.
foreach (var item in list) {...}
In einer using-Anweisung.
using (var file = new StreamReader("C:\\myfile.txt")) {...}
Weitere Informationen finden Sie unter Vorgehensweise: Verwenden von implizit typisierten lokalen Variablen und Arrays in einem Abfrageausdruck.
var und anonyme Typen
In vielen Fällen ist der Einsatz von var
optional und nur eine praktische Syntax. Wenn eine Variable allerdings mit einem anonymen Typ initialisiert wird, müssen Sie die Variable als var
deklarieren, wenn Sie zu einem späteren Zeitpunkt auf die Eigenschaften des Objekts zugreifen möchten. Das ist ein häufiges Szenario in LINQ-Abfrageausdrücken. Weitere Informationen finden Sie unter Anonyme Typen.
Aus der Perspektive Ihres Quellcodes hat ein anonymer Typ keinen Namen. Wenn eine Abfragevariable mit var
initialisiert wurde, ist es deshalb nur möglich, auf die Eigenschaften in der zurückgegebenen Objektsequenz zuzugreifen, wenn Sie var
in der foreach
-Anweisung als Typen der Iterationvariablen verwenden.
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
*/
Hinweise
Die folgenden Einschränkungen gelten für implizit typisierte Variablendeklarationen:
var
kann nur verwendet werden, wenn eine lokale Variable deklariert und in derselben Anweisung initialisiert wird; die Variable kann weder mit NULL noch mit einer Methodengruppe oder einer anonymen Funktion initialisiert werden.var
kann nicht für Felder im Klassenbereich verwendet werden.Variablen, die mit
var
deklariert wurden, können nicht im Initialisierungsausdruck verwendet werden. Sprich, dieser Ausdruck ist gültig:int i = (i = 20);
, aber dieser Ausdruck führt zu einem Kompilierzeitfehler:var i = (i = 20);
Es können nicht mehrere implizit typisierte Variablen in derselben Anweisung initialisiert werden.
Wenn sich ein Typ mit dem Namen
var
im Geltungsbereich befindet, löst sich dasvar
-Schlüsselwort zu diesem Typnamen auf und wird nicht als Teil der Deklaration einer implizit typisierten lokalen Variablen behandelt.
Implizite Typisierung mit dem var
-Schlüsselwort kann nur auf Variablen im Gültigkeitsbereich der lokalen Methode angewendet werden. Implizite Typisierung ist für Klassenfelder nicht verfügbar, weil der C#-Compiler während der Verarbeitung des Codes auf ein logisches Paradox treffen würde: Der Compiler muss den Typ des Felds kennen, aber er kann den Typ erst bestimmen, wenn der Zuordnungsausdruck analysiert ist, und der Ausdruck kann nicht ohne Kenntnis des Typs ausgewertet werden. Betrachten Sie folgenden Code:
private var bookTitles;
bookTitles
ist ein Klassenfeld, das den Typ var
erhält. Da das Feld keinen Ausdruck zur Auswertung enthält, kann der Compiler nicht ableiten, von welchem Typ bookTitles
ist. Darüber hinaus ist es auch nicht ausreichend, dem Feld einen Ausdruck hinzuzufügen (wie für eine lokale Variable):
private var bookTitles = new List<string>();
Wenn der Compiler während der Codekompilierung auf Felder trifft, zeichnet er den Typ jedes Felds auf, bevor er dem Feld zugeordnete Ausdrücke verarbeitet. Der Compiler erkennt das gleiche Paradox bei dem Versuch, bookTitles
zu analysieren: Er muss den Typ des Felds kennen, aber der Compiler würde den Typ von var
normalerweise durch Analysieren des Ausdrucks bestimmen, was nicht möglich ist, ohne vorher den Typ zu kennen.
var
erweist sich auch bei Abfrageausdrücken als nützlich, deren genauer konstruierter Typ der Abfragevariable schwer ermittelbar ist. Dies kann bei Gruppierungs- und Sortierungsvorgängen auftreten.
Das var
-Schlüsselwort erweist sich auch als nützlich, wenn es umständlich ist, den Variablentypen mit der Tastatur einzugeben – oder wenn der Typ offensichtlich ist, oder nicht zur Lesbarkeit des Codes beiträgt. var
ist z.B. bei geschachtelten generischen Typen wie die, die in Gruppenvorgängen verwendet werden, auf diese Weise nützlich. In der folgenden Abfrage ist der Typ der Abfragevariablen IEnumerable<IGrouping<string, Student>>
. Solange dies Ihnen und denen, die Ihren Code verwalten müssen, klar ist, spricht nichts dagegen, implizite Typisierung aus Gründen der Zweckmäßigkeit und der Kürze zu verwenden.
// 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;
Die Verwendung von var
trägt zur Vereinfachung Ihres Codes bei, aber die Verwendung sollte auf die Fälle beschränkt werden, in denen sie erforderlich ist oder wenn sie Ihren Code leichter lesbar macht. Weitere Informationen zur ordnungsgemäßen Verwendung von var
finden Sie im Abschnitt Implizit typisierte lokale Variablen im Artikel zu „C#-Richtlinien für das Codieren“.