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.

292voto

Matt Hamilton Punkte 193704

Ich denke immer noch var kann in manchen Fällen die Lesbarkeit des Codes verbessern. Wenn ich eine Klasse "Customer" mit einer Eigenschaft "Orders" habe und diese einer Variablen zuweisen möchte, mache ich einfach Folgendes:

var orders = cust.Orders;

Es ist mir egal, ob Customer.Orders IEnumerable<Order> , ObservableCollection<Order> o BindingList<Order> - alles, was ich will, ist, diese Liste im Speicher zu halten, um über sie zu iterieren oder ihre Anzahl oder etwas später zu erhalten.

Vergleichen Sie die obige Erklärung mit:

ObservableCollection<Order> orders = cust.Orders;

Für mich ist der Typenname nur ein Geräusch. Und wenn ich zurückkehre und beschließe, den Typ von Customer.Orders zu ändern (z. B. von ObservableCollection<Order> a IList<Order> ), dann muss ich auch diese Deklaration ändern - etwas, das ich nicht tun müsste, wenn ich von vornherein var verwendet hätte.

167voto

Konrad Rudolph Punkte 503837

Ich benutze var umfangreich. Es wurde kritisiert, dass dies die Lesbarkeit des Codes beeinträchtigt, aber es gibt keine Argumente, die diese Behauptung stützen.

Zugegeben, es kann bedeuten, dass nicht klar ist, mit welchem Typ wir es zu tun haben. Aber was soll's? Das ist ja gerade der Sinn eines entkoppelten Designs. Wenn man es mit Schnittstellen zu tun hat, ist man nachdrücklich no sich für den Typ einer Variablen interessieren. var geht zwar viel weiter, aber ich denke, dass das Argument aus Sicht der Lesbarkeit dasselbe bleibt: Der Programmierer sollte sich eigentlich nicht für den Typ der Variablen interessieren, sondern eher dafür, was eine Variable fait . Aus diesem Grund nennt Microsoft die Typinferenz auch "Duck Typing".

Was macht also eine Variable, wenn ich sie mit var ? Ganz einfach, es tut, was immer IntelliSense mir sagt, es tut. Jede Argumentation über C#, die die IDE ignoriert, geht an der Realität vorbei. In der Praxis wird jeder C#-Code in einer IDE programmiert, die IntelliSense unterstützt.

Wenn ich eine var deklariert und verwirrt ist, wofür die Variable da ist, dann stimmt etwas grundlegend nicht mit meinem Code. var ist nicht die Ursache, sie macht nur die Symptome sichtbar. Beschuldigen Sie nicht den Überbringer.

Jetzt hat das C#-Team eine Kodierungsrichtlinie veröffentlicht, die besagt, dass var sollte sólo verwendet werden, um das Ergebnis einer LINQ-Anweisung zu erfassen, die einen anonymen Typ erzeugt (denn hier haben wir keine echte Alternative zu var ). Na ja, was soll's. Solange das C#-Team mir kein stichhaltiges Argument für diese Richtlinie liefert, werde ich sie ignorieren, denn meiner beruflichen und persönlichen Meinung nach ist sie reiner Unsinn. (Tut mir leid, ich habe keinen Link zu der fraglichen Leitlinie).

Tatsächlich gibt es einige (oberflächliche) gute Erklärungen darüber, warum Sie nicht verwenden sollten var aber ich glaube immer noch, dass sie weitgehend falsch sind. Nehmen wir das Beispiel der "Auffindbarkeit": Der Autor behauptet, dass var macht es schwer, nach Orten zu suchen, an denen MyType verwendet wird. Das stimmt. Das gilt auch für Schnittstellen. Warum sollte ich eigentlich wissen wollen, wo die Klasse verwendet wird? Mich interessiert vielleicht eher, wo sie instanziiert wird, und das wird immer noch auffindbar sein, weil irgendwo ihr Konstruktor aufgerufen werden muss (selbst wenn dies indirekt geschieht, muss der Typname irgendwo erwähnt werden).

118voto

tvanfosson Punkte 506878

Var ist meiner Meinung nach in C# eine gute Sache tm . Jede so typisierte Variable ist immer noch stark typisiert, aber sie erhält ihren Typ von der rechten Seite der Zuweisung, in der sie definiert ist. Da die Typinformation auf der rechten Seite verfügbar ist, ist es in den meisten Fällen unnötig und übermäßig langatmig, sie auch auf der linken Seite einzugeben. Ich denke, dass dies die Lesbarkeit deutlich erhöht, ohne die Typsicherheit zu verringern.

Aus meiner Sicht ist die Verwendung guter Namenskonventionen für Variablen und Methoden aus Sicht der Lesbarkeit wichtiger als explizite Typinformationen. Wenn ich die Typinformationen benötige, kann ich jederzeit den Mauszeiger über die Variable (in VS) bewegen und sie abrufen. Im Allgemeinen sollten explizite Typinformationen für den Leser jedoch nicht notwendig sein. Für den Entwickler gibt es in VS immer noch Intellisense, unabhängig davon, wie die Variable deklariert ist. Dennoch kann es Fälle geben, in denen es sinnvoll ist, den Typ explizit zu deklarieren - vielleicht haben Sie eine Methode, die einen List<T> aber Sie wollen es als eine IEnumerable<T> in Ihrer Methode. Um sicherzustellen, dass Sie die Schnittstelle verwenden, kann die Deklaration der Variablen vom Typ der Schnittstelle dies explizit machen. Vielleicht möchten Sie aber auch eine Variable ohne Anfangswert deklarieren, weil sie aufgrund einer Bedingung sofort einen Wert erhält. In diesem Fall benötigen Sie den Typ. Wenn die Typinformation nützlich oder notwendig ist, sollten Sie sie verwenden. Ich bin jedoch der Meinung, dass sie in der Regel nicht notwendig ist und der Code ohne sie in den meisten Fällen leichter zu lesen ist.

91voto

Adam Robinson Punkte 176996

Keines von beidem ist absolut wahr; var kann sowohl positive als auch negative Auswirkungen auf die Lesbarkeit haben. Meiner Meinung nach, var sollte verwendet werden, wenn einer der folgenden Punkte zutrifft:

  1. Der Typ ist anonym (Sie haben hier keine Wahl, da er doit in diesem Fall var sein)
  2. Der Typ ist offensichtlich auf der Grundlage des zugewiesenen Ausdrucks (d. h. var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating() )

var hat keine Auswirkungen auf die Leistung, da es sich um syntaktischen Zucker handelt; der Compiler leitet den Typ ab und definiert ihn, sobald er in AWL kompiliert ist; es gibt nichts eigentlich dynamisch zu sein.

68voto

Dustman Punkte 4797

Von Eric Lippert, einem Senior Software Design Engineer im C#-Team:

Warum war die var Schlüsselwort eingeführt?

Dafür gibt es zwei Gründe, von denen einer einen, der heute existiert, und einen, der 3.0 auftauchen wird.

Der erste Grund ist, dass dieser Code unglaublich hässlich ist, wegen der vielen Redundanz:

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

Und das ist ein einfaches Beispiel - ich habe Schlimmeres geschrieben. Jedes Mal, wenn man gezwungen ist genau das Gleiche zweimal zu tippen, ist das eine Redundanz, die wir beseitigen können. Viel schöner ist es zu schreiben

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

und lassen den Compiler herausfinden, was den Typ anhand der Zuweisung.

Zweitens führt C# 3.0 anonyme Typen ein. Da anonyme Typen per Definition keine Namen haben, können Sie brauchen auf in der Lage zu sein, den Typ der Variablen aus der initialisierenden Ausdruck ableiten zu können, wenn ihr Typ anonym ist.

Hervorhebung von mir. Der ganze Artikel, C# 3.0 ist immer noch statisch typisiert, ehrlich! und die darauf folgende Serie sind ziemlich gut.

Das ist es, was var ist für. Andere Verwendungen werden wahrscheinlich nicht so gut funktionieren. Jeder Vergleich mit JScript, VBScript oder dynamischer Typisierung ist völliger Quatsch. Nochmals der Hinweis, var es erforderlich um bestimmte andere Funktionen in .NET nutzen zu können.

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