405 Stimmen

Verwendung des Schlüsselworts var in C#

Nach einer Diskussion mit Kollegen über die Verwendung des Schlüsselworts "var" in C# 3 habe ich mich gefragt, welche Meinung die Leute zur angemessenen Verwendung der Typinferenz über var haben?

Zum Beispiel habe ich var in fragwürdigen Situationen ziemlich faul verwendet, z.B.:-

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

Weitere legitime Verwendungszwecke von var sind folgende:-

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

Interessanterweise scheint LINQ eine Art Grauzone zu sein, z.B.:-

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

Es ist klar, was daraus resultiert, dass es sich um einen Typ handelt, der IEnumerable implementiert, aber es ist nicht ganz so offensichtlich wie bei einer var, die ein neues Objekt deklariert.

Noch schlimmer ist es, wenn es um LINQ to objects geht, z.B.:-

var results = from item in someList
              where item != 3
              select item;

Dies ist nicht besser als das Äquivilent foreach(var item in someList) { // ... } gleichwertig.

Es gibt hier ein echtes Problem mit der Typsicherheit - wenn wir zum Beispiel die Ergebnisse dieser Abfrage in eine überladene Methode stellen würden, die IEnumerable<int> und IEnumerable<double> akzeptiert, könnte der Aufrufer versehentlich den falschen Typ übergeben.

var fait eine starke Typisierung beibehalten, aber die Frage ist, ob es gefährlich ist, wenn der Typ bei der Definition nicht sofort ersichtlich ist, was noch verstärkt wird, wenn Überladungen bedeuten, dass Compilerfehler nicht ausgegeben werden, wenn Sie einer Methode versehentlich den falschen Typ übergeben.

53voto

Matt Hamilton Punkte 193704

Ich denke, die Verwendung von var sollte mit klug gewählten Variablennamen gekoppelt sein.

Ich habe kein Problem damit, var in einer foreach-Anweisung zu verwenden, vorausgesetzt, es ist nicht so wie hier:

foreach (var c in list) { ... }

Wenn es eher so wäre:

foreach (var customer in list) { ... }

... dann würde jemand, der den Code liest, viel eher verstehen, was "Liste" ist. Wenn Sie die Kontrolle über den Namen der Listenvariablen selbst haben, ist das sogar noch besser.

Das Gleiche gilt für andere Situationen. Das ist ziemlich nutzlos:

var x = SaveFoo(foo);

... aber das macht Sinn:

var saveSucceeded = SaveFoo(foo);

Jedem das Seine, denke ich. Ich habe mich dabei ertappt, dass ich das tue, was einfach verrückt ist:

var f = (float)3;

Ich brauche eine Art 12-Schritte-Programm. Mein Name ist Matt, und ich (miss)brauche var.

40voto

Dexter Punkte 17687

Wir haben uns das Ethos "Code für Menschen, nicht für Maschinen" zu eigen gemacht, basierend auf der Annahme, dass man im Wartungsmodus ein Vielfaches mehr Zeit verbringt als bei der Neuentwicklung.

Das Argument, dass der Compiler "weiß", um welchen Typ es sich bei der Variable handelt, ist für mich nicht stichhaltig. Sicher, man kann beim ersten Mal keinen ungültigen Code schreiben, weil der Compiler die Kompilierung des Codes verhindert, aber wenn der nächste Entwickler den Code in sechs Monaten liest, muss er in der Lage sein, daraus abzuleiten, was die Variable richtig oder falsch macht, und die Ursache von Problemen schnell zu erkennen.

So,

var something = SomeMethod();

ist nach unseren Kodierungsstandards verboten, aber das Folgende wird in unserem Team gefördert, weil es die Lesbarkeit erhöht:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

39voto

Es ist nicht schlecht, es ist eher eine stilistische Sache, die eher subjektiv ist. Es kann zu Unstimmigkeiten führen, wenn Sie var verwenden und wenn nicht.

Ein weiterer bedenklicher Fall ist der folgende Aufruf, bei dem man anhand des Codes nicht erkennen kann, welcher Typ von CallMe :

var variable = CallMe();

Das ist mein Hauptkritikpunkt an var.

Ich verwende var, wenn ich anonyme Delegierte in Methoden deklariere, irgendwie sieht var sauberer aus, als wenn ich verwenden würde Func . Betrachten Sie diesen Code:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

EDITAR : Das letzte Codebeispiel wurde aufgrund von Julians Anregungen aktualisiert.

36voto

Kate Gregory Punkte 18638

Var ist ganz und gar nicht wie Variante. Die Variable ist immer noch stark typisiert, man drückt nur keine Tasten, um sie auf diese Weise zu erhalten. Sie können den Mauszeiger in Visual Studio über die Variable bewegen, um den Typ zu sehen. Wenn Sie gedruckten Code lesen, müssen Sie möglicherweise ein wenig nachdenken, um den Typ herauszufinden. Aber es gibt nur eine Zeile, in der er deklariert wird, und viele Zeilen, die ihn verwenden, so dass es immer noch am besten ist, den Code übersichtlich zu gestalten, indem man den Dingen anständige Namen gibt.

Ist die Verwendung von Intellisense faul? Es ist weniger Tipparbeit als der ganze Name. Oder gibt es Dinge, die weniger Arbeit machen, aber keine Kritik verdienen? Ich denke, es gibt sie, und var ist eines von ihnen.

27voto

Marc Gravell Punkte 970173

Die wahrscheinlichste Zeit, die Sie benötigen, ist für anonyme Typen (wo es 100% erforderlich ist); aber es vermeidet auch Wiederholung für die trivialen Fälle, und IMO macht die Zeile klarer. Ich brauche den Typ nicht zweimal für eine einfache Initialisierung zu sehen.

Zum Beispiel:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(bitte die hscroll in der obigen Abbildung nicht bearbeiten - das beweist den Sinn!!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

Es gibt jedoch Fälle, in denen dies irreführend ist und zu Fehlern führen kann. Seien Sie vorsichtig mit var wenn die ursprüngliche Variable und der initialisierte Typ nicht identisch waren. Zum Beispiel:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X