Was zu verwenden: var oder Objektnamen Typ? [Duplikat]
-
04-07-2019 - |
Frage
Diese Frage bereits eine Antwort hier:
- Verwendung von var Schlüsselwort in C # 86 Antworten
Dies ist eine Frage, die bei der Programmierung ich immer frage mich: Was ist zu verwenden, wenn wir schreiben Code:
var myFiles = Directory.GetFiles(fullPath);
oder
string[] myFiles = Directory.GetFiles(fullPath);
var ist neu und ist ein Implizit typisierte lokale Variablen , so können wir nur lokal verwenden und es hat Regeln wie kann nicht sein, null, etc., aber ich frage mich, ob wir einen Vorteil der Verwendung es „normal“ zu bekommen.
Die "normal" Teil sagt, nicht in Anonyme Typen , Objekt und Auflistungsinitialisierer und Abfrage-Ausdrücke Dabei gilt, dass die Absicht war zu verwenden, das var anonyme Objekt, also was ich meine ist ... genau wie das Beispiel oben.
Was sind Ihre Gedanken?
Lösung
Neben den offensichtlichen Einsatz von var
mit LINQ, ich benutze es auch behaarte Variablendeklarationen zur besseren Lesbarkeit abzukürzen, z.
var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();
In der Regel bekomme ich eine Art von Komfort (in Ermangelung eines besseren Wortes) von statischer Typisierung, die ich nur ungern macht es aufgeben. Ich mag das Gefühl, dass ich weiß, was ich tue, wenn ich eine Variable zu deklarieren. Deklarieren eine Variable der Compiler nicht nur etwas zu sagen, es sagt die Person, die Ihr Code etwas zu lesen.
Lassen Sie mich Ihnen ein Beispiel geben. Angenommen, ich eine Methode, die eine List<string>
zurückgibt. Dieser Code ist sicher richtig, und ich denke, es ist, wie 90% der C # Entwickler wäre es wahrscheinlich schreiben:
List<string> list = MyMethod();
Natürlich, nicht wahr? In der Tat, hier ist ein Ort, den Sie genauso einfach var
nutzen könnten.
True genug. Aber diese Version des Codes ist nicht nur eine Variable deklarieren, es mir zu sagen, was die Person, die schrieb, es zu tun beabsichtigt:
IEnumerable<string> list = MyMethod();
Der Entwickler, der schrieb, dass Code sagt mir: „Ich werde diese Liste nicht zu ändern, noch werde ich einen Index verwenden, um ihre Mitglieder zugreifen. Alles, was ich tun werde ist über sie iterieren.“ Das ist eine Menge von Informationen in einer einzigen Zeile Code zu vermitteln. Es ist etwas, das Sie aufgeben, wenn Sie var
verwenden.
Natürlich Sie geben es nicht auf, wenn Sie es nicht in erster Linie verwendet haben. Wenn Sie die Art von Entwickler sind, der diese Zeile Code schreiben würde, wissen Sie bereits, dass Sie var
dort nicht verwenden würde.
Edit:
Ich lese gerade Jon Skeet Post, und dieses Zitat von Eric Lippert sprang auf mich:
Implizit typisierte Einheimischen sind nur ein kleiner Weg, in dem Sie die wie deemphasize und dadurch betonen das, was.
Ich denke, dass tatsächlich in vielen Fällen implizite Typisierung mit verlässt das, was implizit. Es ist nur OK, um nicht auf das, was zu wohnen.
: Zum Beispiel werde ich zufällig eine LINQ-Abfrage wie schreibenvar rows = from DataRow r in parentRow.GetChildRows(myRelation)
where r.Field<bool>("Flag")
orderby r.Field<int>("SortKey")
select r;
Wenn ich diesen Code zu lesen, eines der Dinge, die ich denke, wenn ich es bin zu lesen ist „rows
ein IEnumerable<DataRow>
ist.“ Weil ich weiß, dass LINQ-Abfragen, was Rückkehr ist IEnumerable<T>
, und ich kann die Art des Objekts sehen genau dort ausgewählt werden.
Das ist ein Fall, in dem das, was nicht explizit gemacht worden. Es wurde für mich übrig zu schließen.
Jetzt in etwa 90% der Fälle, in denen ich LINQ verwenden, ist dies nicht ein ganz klein wenig Materie. Da 90% der Zeit, die nächste Codezeile:
foreach (DataRow r in rows)
Aber es ist nicht schwer, den Code zu vergegenwärtigen, in der es sehr nützlich wäre rows
als IEnumerable<DataRow>
zu erklären - Code, in dem viele verschiedene Arten von Objekten abgefragt wurden, war es nicht möglich, die Abfrage Erklärung der Iteration neben setzen und es wäre nützlich, in der Lage sein rows
mit IntelliSense inspizieren. Und das ist eine Sache, was, nicht wie Sache.
Andere Tipps
Sie bieten eine große Vielfalt an Meinungen zu dieser bekommen „nur var mit anonymen Typen verwenden, wo man im Grunde zu haben.“ Ich mag Eric Lippert nehmen auf sie :
Der gesamte Code ist eine Abstraktion. Ist, was der Code ist „wirklich“ zu tun ist Manipulieren von Daten? Nr Zahlen? Bits? Nr Spannungen? Nr Elektronen? Ja aber den Code zu verstehen, auf der Ebene der Elektronen sind eine schlechte Idee! Die Kunst der Codierung ist es, herauszufinden, was die richtige Abstraktionsebene ist für die Publikum.
In einer Hochsprache ist immer diese Spannung zwischen dem, was dem Code tut (semantisch) und wie die Code erreicht es. Instandhaltung Programmierer müssen beide verstehen das Was und das, wie wenn sie gehen, das bei der Herstellung Änderungen erfolgreich zu sein.
Der ganze Sinn von LINQ ist, dass es massiv de-betont das „Wie“ und massiv betont die „was“. Durch Verwendung einer Abfrage Verständnis, die Programmierer sagt, in die Zukunft Publikum: „Ich glaube, dass Sie sollten weder wissen noch egal, wie genau diese Ergebnismenge berechnet wird, aber Sie sollte sehr viel darum kümmern, was die Semantik des resultierenden Satzes ist.“ Sie machen den Code näher an die Geschäftsprozess umgesetzt und weiter von den Bits und Elektronen dass es gehen.
Implizit typisierte Einheimischen sind nur ein kleine Art und Weise, in der Sie deemphasize können die, wie und betonen dadurch die Was. Ob das das Richtige in einem bestimmten Fall zu tun ist, ein Urteil nennen. Also ich sage den Leuten, dass wenn ihre Kenntnis von der Art ist relevant und seine Wahl ist entscheidend für die ein fortgesetzter Betrieb des Verfahrens, nicht implizite Typisierung dann verwenden. Explizite Typisierung sagt: „Ich sage Ihnen wie dies aus einem Grund funktioniert, zahlen Aufmerksamkeit „sagt Implizite Typisierung“ es nicht ein wenig, ob diese Rolle Sache ist, eine Liste oder eine Kunde [], was zählt, ist, dass es eine Sammlung von Kunden. "
Persönlich ich nicht neigen , es zu benutzen, wenn der Typ nicht recht klar ist -, wo ich LINQ-Abfragen sind als „vernünftigerweise offensichtlich“ zu sein. Ich würde es nicht zum Beispiel für Directory.GetFiles
tun, da es nicht wirklich offensichtlich ist, dass das eine string[]
kehrt anstelle von (sagen wir) eine FileInfo[]
(oder etwas ganz anderes) - und das macht einen großen Unterschied zu dem, was Sie später tun
Wenn es auf der rechten Seite des Zuweisungsoperators ein Konstruktoraufruf ist, bin ich viel eher mit var
gehen: es ganz offensichtlich ist, was der Typ sein wird. Dies ist besonders praktisch bei komplexen generischen Typen, z.B. Dictionary<string,List<int>>
.
Ich persönlich verwende nur var an zwei Stellen:
- Mit anonymen Typen, dh. LINQ-bezogene (wo var ist in einigen Fällen erforderlich)
- Wenn die Anweisung deklariert und konstruiert einen bestimmten Typ in der gleichen Art
dh. Dies ist ein Beispiel für Punkt 2:
var names = new List<String>();
Edited . Dies als Antwort auf Jon Skeet Frage
Die obige Antwort wurde in der Tat vereinfacht. Grundsätzlich verwende ich var , wo der Typ ist entweder:
- Unnötig zu wissen (nicht so viele Orte, obwohl)
- unmöglich zu wissen (LINQ, anonyme Typen)
- Andernfalls bekannt, oder aus dem Code
Im Fall einer Factory-Methode, wo alles, was Sie brauchen, an dem Ort, zu wissen, wo Sie den Code zu schreiben ist, dass das Objekt, das Sie zurück zu erhalten, ist ein Nachkomme eines Typs, und das eine Art eine statische Factory-Methode hat, dann würde ich var verwenden. Wie folgt aus:
var connection = DatabaseConnection.CreateFromConnectionString("...");
Das obige Beispiel ist ein echtes Beispiel aus meinem Code. Es ist klar, zumindest für mich und die Menschen, die diesen Code verwenden, dass Verbindung ein Database Nachkomme ist, aber der genaue Typ ist nicht erforderlich für weder den Code zu verstehen, noch es zu benutzen.
Ich habe versucht, die „Verwendung var überall“ Stil ... und hier ist, warum ich nicht weiter verwenden.
- Gestörter Lesbarkeit manchmal
- Limits Intellisense nach =
- Die Eingabe von "var" war wirklich nicht viel kürzer als "int", "string" usw. eingeben, vor allem mit Intellisense.
Mit diesem wird gesagt, ich tue es immer noch mit LINQ verwenden.
Aus dem Land der funktionalen Programmierung, in dem Typ-Inferenz den Tag regiert, verwende ich var
für alle Einheimischen, wo immer möglich.
In Visual Studio, wenn Sie jemals fragen sich, was die Art eines lokal ist, alles, was Sie tun müssen, ist schweben über sie mit der Maus.
Das post haben einige gute guidlines auf, wenn var Interface oder Objekttypen verwenden.
Ich neige dazu, var
überall zu verwenden, aber meine Mitarbeiter den Anschlag, es weniger lesbar für uns ist. Also habe ich jetzt benutze ich var
nur auf anonyme Typen, LINQ-Abfragen und wo ist Konstruktor auf der rechten Seite.
Ich denke, es ist interessant zu sehen, wie dies in der Regel in Haskell behandelt wird. Dank der Curry-Howard Isomorphismus , der (allgemeinsten) Typ eines Ausdrucks in Haskell kann abgeleitet werden, und somit sind Erklärungen gibt im wesentlichen nicht überall erforderlich, mit wenigen Ausnahmen; zum Beispiel, manchmal will man bewusst würde gefolgert den Typen etwas spezifischer als begrenzen.
Natürlich, was erforderlich ist, und was wird empfohlen, ist nicht dasselbe; In der Praxis scheint die Konvention zu sein, dass Top-Level-Definitionen Typdeklarationen immer haben, während lokalisierten Definitionen die Typdeklarationen ausgelassen haben. Dies scheint zwischen Explizit-for-Lesbarkeit der Definition als Ganze gegen mit Kürze for Lesbarkeit der lokalen „Helfer“ oder „vorübergehend“ Definitionen eine gute Balance zu finden. Wenn ich richtig verstehe, kann man nicht var
für „Top-Level“ Definitionen (wie eine Methode oder globale Funktion) in erster Linie verwenden, so dass ich denke, das übersetzt „var
verwendet überall können Sie“ in C # Welt. Natürlich ist die gleiche Anzahl der Tastenanschläge „int
“ eingeben als „var
“, aber die meisten Beispiele werden länger als das.