Verwendung des Schlüsselworts var in C #

406

Nach einer Diskussion mit Kollegen über die Verwendung des Schlüsselworts 'var' in C # 3 fragte ich mich, wie die Meinung der Leute zu den geeigneten Verwendungen der Typinferenz über var war.

Zum Beispiel habe ich var unter fragwürdigen Umständen eher faul benutzt, zB: -

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 Verwendungen von var sind: -

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

Interessanterweise scheint LINQ eine 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, welche Ergebnisse sich daraus ergeben werden, dass es sich um einen Typ handelt, der IEnumerable implementiert. Es ist jedoch nicht ganz so offensichtlich, wie es sich für eine var handelt, die ein neues Objekt deklariert.

Es ist noch schlimmer, wenn es um LINQ für Objekte geht, zB: -

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

Dies ist nicht besser als das gleichwertige foreach (var item in someList) {// ...} equivilent.

Hier besteht ein echtes Problem hinsichtlich der Typensicherheit. Wenn wir beispielsweise die Ergebnisse dieser Abfrage in eine überladene Methode einfügen, die IEnumerable <int> und IEnumerable <double> akzeptiert, übergibt der Aufrufer möglicherweise versehentlich den falschen Typ.

var Die Typisierung ist zwar stark, aber die Frage ist wirklich, ob es gefährlich ist, wenn der Typ bei der Definition nicht sofort erkennbar ist. Dies wird vergrößert, wenn Überladungen dazu führen, dass Compilerfehler möglicherweise nicht ausgegeben werden, wenn Sie den falschen Typ unbeabsichtigt an eine Methode übergeben.

ljs
quelle
68
Die Verwendung von var ist in Ordnung, aber "Ich muss den Typ nicht herausfinden" scheint ein sehr schlechter Grund zu sein, ihn zu verwenden. Sie sollten wissen, was der Typ ist. Var ist nur eine Verknüpfung, um eine Eingabe zu vermeiden
Thomas Levesque
53
var i = 0;== scheitern! var c = new CrazyFrigginLongClassName();== gewinnen!
Dotjoe
6
"Var erinnert mich auch an den VB / VBA-Variantentyp. Er hatte auch seinen Platz. Ich erinnere mich (vor vielen Jahren), dass seine Verwendung weniger als wünschenswert war und eher ressourcenhungrig." <- zeigt, dass dies eine Köderfrage ist, da der 'var'-Typ von C # nichts mit dem VB / VBA-Variantentyp zu tun hat.
user7116
20
var readabilityBeDamned = true;
Spoulson
9
Das Problem bei allen hier genannten Beispielen ist, dass wir uns EINE Codezeile ansehen. Wenn ich Zeile für Zeile "var" -Deklarationen nacheinander sehe, gerät dies außer Kontrolle. Die Lesbarkeit ist subjektiv, aber ich finde, dass var weit mehr missbraucht als respektabel verwendet wird.
jro

Antworten:

293

Ich denke varimmer noch, dass Code in einigen Fällen besser lesbar sein kann. Wenn ich eine Kundenklasse mit einer Orders-Eigenschaft habe und diese einer Variablen zuweisen möchte, gehe ich einfach so vor:

var orders = cust.Orders;

Ich interessiere mich nicht , wenn Customer.Orders ist IEnumerable<Order>, ObservableCollection<Order>oder BindingList<Order>- alles , was ich will , ist , dass die Liste im Speicher zu iterieren halten oder seine Zählung oder etwas bekommen später.

Vergleichen Sie die obige Erklärung mit:

ObservableCollection<Order> orders = cust.Orders;

Für mich ist der Typname nur Rauschen. Und wenn ich zurückgehe und mich entscheide, den Typ des Kunden zu ändern. Bestellungen später (etwa von ObservableCollection<Order>bis IList<Order>), dann muss ich auch diese Deklaration ändern - etwas, das ich nicht tun müsste, wenn ich in der ersten var verwendet hätte Ort.

Matt Hamilton
quelle
48
Ich mag es, den expliziten Typ vor mir zu haben, wenn ich Code lese. Woher weiß ich, was "cust.Orders" hier ohne den Typ ist? Ja, ich könnte meine Maus darüber bewegen, um es herauszufinden, aber warum sollte ich müssen? :)
Jon Tackabury
77
Aber der Punkt ist, dass es im Allgemeinen keine Rolle spielt. Vorausgesetzt, cust.Orders ist etwas, das Sie aufzählen können (z. B. foreach over), dann spielt es keine Rolle, um welchen Typ es sich handelt. Der zusätzliche Code behindert nur das Lesen der Absicht.
Matt Hamilton
67
Wenn Sie jedoch nur cust.Orders benötigen, ist dies "etwas, das Sie aufzählen können". Wenn Sie es dann nicht als IEnumerable <Order> deklarieren, wird diese Anforderung explizit und klar? Wenn Sie es als var deklarieren, verlieren Sie diese Anforderung effektiv.
GrahamS
5
@jon und wie würden IEnumerbal-Bestellungen = cust.Orders foreach (var order in orders) einen Unterschied machen? Das einzige, was IEnumerable sagt, ist, dass Sie es in einen Foreach legen können, aber Sie wussten das bereits aus der folgenden Zeile
Rune FS
18
"Das einzige, was IEnumerable sagt, ist, dass Sie es in einen foreach legen können" - es drückt auch die Absicht aus, dass das einzige, was Sie tun können, das Aufzählen ist. Durch die Verwendung von var erhalten öffentliche Mitglieder des konkreten Sammlungstyps Zugriff auf und Intellisense.
Joe
167

Ich benutze varausgiebig. Es wurde kritisiert, dass dies die Lesbarkeit des Codes beeinträchtigt, aber kein Argument, um diese Behauptung zu stützen.

Zugegeben, es kann bedeuten, dass nicht klar ist, um welchen Typ es sich handelt. Na und? Dies ist eigentlich der Punkt eines entkoppelten Designs. Beim Umgang mit Schnittstellen interessiert Sie nachdrücklich nicht der Typ einer Variablen. vargeht zwar viel weiter, aber ich denke, dass das Argument unter dem Gesichtspunkt der Lesbarkeit dasselbe bleibt: Der Programmierer sollte eigentlich nicht am Typ der Variablen interessiert sein, sondern daran, was eine Variable tut . Aus diesem Grund nennt Microsoft die Typinferenz auch "Ententypisierung".

Was macht eine Variable, wenn ich sie mit deklariere var? Ganz einfach, es macht alles, was IntelliSense mir sagt. Alle Überlegungen zu C #, die die IDE ignorieren, bleiben hinter der Realität zurück. In der Praxis wird jeder C # -Code in einer IDE programmiert, die IntelliSense unterstützt.

Wenn ich eine vardeklarierte Variable verwende und verwirrt bin, wofür die Variable da ist, stimmt etwas grundlegend mit meinem Code nicht. varist nicht die Ursache, es macht nur die Symptome sichtbar. Beschuldige nicht den Boten.

Nun hat das C # Team eine Codierung Richtlinie veröffentlicht die besagt , dass varsollte nur das Ergebnis einer LINQ - Anweisung zu erfassen verwendet werden , die einen anonymen Typ erzeugt (weil hier, wir haben keine wirkliche Alternative zu var). Nun, scheiß drauf. Solange das C # -Team mir kein stichhaltiges Argument für diese Richtlinie gibt, werde ich sie ignorieren, da es meiner beruflichen und persönlichen Meinung nach reiner Quatsch ist. (Entschuldigung; ich habe keinen Link zu der fraglichen Richtlinie.)

Eigentlich gibt es einige (oberflächlich) gute Erklärungen, warum Sie sie nicht verwenden sollten, varaber ich glaube immer noch, dass sie größtenteils falsch sind. Nehmen Sie das Beispiel der „Suchbarkeit“: Der Autor behauptet, vardass es schwierig ist, nach Orten zu suchen, an denen sie MyTypeverwendet werden. Recht. Schnittstellen auch. Warum sollte ich eigentlich wissen wollen, wo die Klasse verwendet wird? Ich könnte mehr daran interessiert sein, wo es instanziiert wird, und dies wird immer noch durchsuchbar sein, da irgendwo sein Konstruktor aufgerufen werden muss (selbst wenn dies indirekt erfolgt, muss der Typname irgendwo erwähnt werden).

Konrad Rudolph
quelle
14
In einer anständigen IDE verwenden Sie keine Textsuche, um die Klassenverwendung zu erhalten. Sie veranlassen die IDE, dies basierend auf dem Analysebaum zu tun, oder sie identifiziert jedoch die Objekttypen. Da es sich um statische Typisierung handelt, werden hier nur die anonymen Typen gefunden.
Dustman
6
Ich würde es hassen, 100.000 Quellzeilen ohne Dokumentation und liberale Verwendung von var zu erben. Vor allem, wenn Sie var mit weniger hilfreichen Variablennamen kombinieren. Ich konnte sehen, dass es hilfreich ist, einen Punkt zu veranschaulichen (oder mit anonymen Typen umzugehen), aber im Produktionscode?
Shea
7
Arnshea: Nun, Sie haben dort bereits auf das eigentliche Problem hingewiesen: die nutzlosen Variablennamen und die fehlende Dokumentation . Ich verstehe wirklich nicht, was varzur Verwirrung beiträgt. Sicherlich kann es Fälle geben, in denen es wichtig ist, den Typ / die Größe einer Variablen hervorzuheben (z. B. Bitoperationen auf niedriger Ebene). Das ist in Ordnung: Niemand hat jemals behauptet, dass vardies ausschließlich verwendet werden sollte. Die Regel ist einfach: Wenn es wirklich Verwirrung stiftet, verwenden Sie es nicht.
Konrad Rudolph
17
Jedes Beispiel im Gegensatz zu var, das ich gesehen habe, geht davon aus, dass der Programmierer bedeutungslose Variablennamen verwendet. Aber vielleicht ist var deshalb besser, als einen Typ explizit anzugeben: Es zwingt den Programmierer, gute Variablennamen zu finden.
Ryan Lundy
16
Microsoft nennt die Typinferenz auch "Ententypisierung". - wirklich? Ich wäre schockiert ...
Anton Tykhyy
118

Var, meiner Meinung nach , in C # ist eine gute Sache tm . Jede so eingegebene Variable ist immer noch stark typisiert, aber ihr Typ wird von der rechten Seite der Zuweisung abgerufen, in der sie definiert ist. Da die Typinformationen auf der rechten Seite verfügbar sind, ist es in den meisten Fällen unnötig und übermäßig ausführlich, sie auch auf der linken Seite eingeben zu müssen. Ich denke, dies erhöht die Lesbarkeit erheblich, ohne die Typensicherheit zu beeinträchtigen.

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 immer mit der Maus über die Variable (in VS) fahren und sie abrufen. Im Allgemeinen sollten explizite Typinformationen für den Leser jedoch nicht erforderlich sein. Für den Entwickler erhalten Sie in VS immer noch Intellisense, unabhängig davon, wie die Variable deklariert ist. Trotzdem kann es immer noch Fälle geben, in denen es sinnvoll ist, den Typ explizit zu deklarieren - vielleicht haben Sie eine Methode, die a zurückgibt List<T>, aber Sie möchten sie als behandelnIEnumerable<T>in Ihrer Methode. Um sicherzustellen, dass Sie die Schnittstelle verwenden, kann dies durch Deklarieren der Variablen des Schnittstellentyps explizit gemacht werden. Oder Sie möchten eine Variable ohne Anfangswert deklarieren, da sie aufgrund einer bestimmten Bedingung sofort einen Wert erhält. In diesem Fall benötigen Sie den Typ. Wenn die Typinformationen nützlich oder notwendig sind, verwenden Sie sie. Ich bin jedoch der Meinung, dass dies normalerweise nicht erforderlich ist und der Code in den meisten Fällen ohne ihn leichter zu lesen ist.

Tvanfosson
quelle
3
Ich stimme insgesamt zu. Der entscheidende Punkt hier ist meiner Meinung nach, dass die Absicht klar ist. Wenn es den meisten Entwicklern im Team nicht klar ist, ist es schädlich und nicht hilfreich. Trotzdem bin ich persönlich ein RIESIGER Fan davon, musste mich aber ein wenig zurückhalten, wenn andere Entwickler in meinem Team Probleme hatten, meine Absicht zu bestimmen. Stelle dir das vor.
Steve Brouillard
3
Eh, ich finde es einfacher zu lesen, wenn der Typ links ist. Mit ReSharper muss ich den Typ auf der rechten Seite sowieso nicht erneut eingeben, daher stört mich das nicht.
BlueRaja - Danny Pflughoeft
1
@BlueRaja - Ich finde, dass die Verwendung guter Variablennamen normalerweise die Notwendigkeit beseitigt, sich ohnehin mit dem tatsächlichen Typ zu beschäftigen, um dies zu verstehen. Intellisense ist weiterhin für "var" -definierte Variablen verfügbar, daher muss ich den Typ nicht kennen, um beim Codieren eine Methode / Eigenschaft darauf auswählen zu können.
Tvanfosson
2
Es geht nicht so sehr darum, wann Sie codieren, sondern darum, wann Sie den Code lesen müssen.
BlueRaja - Danny Pflughoeft
1
Ich muss dann nur auf der dicken Seite sein, ich muss gute Methoden- und Variablennamen und ein Verständnis für die Typen haben, mit denen gearbeitet wird, um den Code, den ich lese, richtig verstehen zu können. Ich denke, Sie haben Recht, obwohl es symptomatisch für größere Probleme ist. Einer des Vertrauens. Um sicherzugehen, dass der Code das tut, was er zu tun scheint, müssen Sie sicher sein , welche Typen verwendet werden.
AnthonyWJones
91

Keines davon ist absolut wahr; varkann sowohl positive als auch negative Auswirkungen auf die Lesbarkeit haben. Sollte meiner Meinung nach varverwendet werden, wenn eine der folgenden Aussagen zutrifft:

  1. Der Typ ist anonym (nun, Sie haben hier keine Wahl, wie es sein muss var in diesem Fall)
  2. Der Typ ist offensichtlich basierend auf dem zugewiesenen Ausdruck (dh var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

varhat keine Auswirkungen auf die Leistung, da es sich um syntaktischen Zucker handelt; Der Compiler leitet den Typ ab und definiert ihn, sobald er in IL kompiliert wurde. Es ist nichts wirklich Dynamisches daran.

Adam Robinson
quelle
1
Ich stimme beiden zu, obwohl ich im zweiten Fall lange Einschränkungen habe. Wenn ein Typ so lang ist, ist er normalerweise ein generischer Typ mit vielen verschachtelten generischen Argumenten. In diesem Fall ist ein stark typisierter "ShortType äquivalent zu TypeWithAReallyLongNameTheresNoSenseRepeating" sinnvoller
Ion Todirel
12
Ich habe keine Lust, einen Religionskrieg zu beginnen, aber ich persönlich neige dazu, Ion nicht zuzustimmen. Ich würde einen sehr langen, aber sehr präzisen Typnamen (ala Onkel Bob Martin) einem abgekürzten und möglicherweise mehrdeutigen kürzeren Typnamen vorziehen. Ich werde die Einschränkung hinzufügen, dass ich nicht damit einverstanden bin, die Länge des Namens künstlich aufzublasen. Wenn 5 Zeichen einen prägnanten Namen erstellen, der die Absicht deutlich zeigt, verwenden Sie 5 und nicht 25.
Steve Brouillard
2
@Steve: Ich muss dir zustimmen; Das Erstellen eines "kurzen Typs" (von dem ich annehme, dass Sie ihn nur zum Zwecke der Verkürzung des Namens vom spezifischen generischen Typ erben) ist keine gute Praxis. Sie müssen alle Konstruktoren des generischen Typs duplizieren und durchlaufen sowie verhindern, dass Sie einen anderen Typ, der vom generischen Typ erbt, an die Funktion übergeben. Sie verwenden die Vererbung wie eine, typedefwenn dies nicht der Fall ist.
Adam Robinson
7
Verwenden, varwenn der Typ offensichtlich ist? Vielleicht, aber der wahre Gewinn ist, wenn der Typ keine Rolle spielt. Wenn Sie solche Dinge tun, spielt var customers = whatever; var query = from c in customers select stuffes keine Rolle, was genau die Art von "Kunden" ist. Es ist offensichtlich, wie Sie es verwenden können, und das ist genug. Und wenn der eigentliche Typ umständlich ist, lohnt es sich, ihn zu unterdrücken.
Joren
2
@Kristoffer: Ich kann verstehen, dass ich das Durcheinander von Tags beseitigen möchte, aber das Einschließen in eine Klasse ist keine (IMO) akzeptable Alternative, da Sie dann die Möglichkeit einer anderen (legitimen) untergeordneten Klasse dieses generischen Typs ausschließen ein gültiger Parameter. Ich würde lieber eine using ShortType = LongGenericType<A,B,C>Direktive am Anfang einer Datei verwenden, da dies die gleiche Lesbarkeit bietet, nicht erfordert, dass Sie die Konstruktoren neu erstellen, und untergeordnete Klassen nicht als Kandidaten ausschließt.
Adam Robinson
68

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

Warum wurde das varSchlüsselwort eingeführt?

Es gibt zwei Gründe, einen, der heute existiert, einen, der in 3.0 auftauchen wird.

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

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

Und das ist ein einfaches Beispiel - ich habe schlechter geschrieben. Jedes Mal, wenn Sie gezwungen sind, zweimal genau dasselbe einzugeben, können wir diese Redundanz entfernen. Viel schöner zu schreiben

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

und lassen Sie den Compiler herausfinden, welcher Typ auf der Zuweisung basiert.

Zweitens führt C # 3.0 anonyme Typen ein. Da anonyme Typen per definitionem keine Namen haben, Sie müssen den Typ der Variable aus der Initialisierung Ausdruck ableiten zu können , wenn seine Art anonym.

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

Dafür ist da var. Andere Anwendungen werden wahrscheinlich nicht so gut funktionieren. Jeder Vergleich mit JScript, VBScript oder dynamischer Typisierung ist eine totale Koje. Hinweis wieder, varist erforderlich , um in .NET bestimmten anderen Merkmalen der Arbeit zu haben.

Dustman
quelle
Ich finde Lipperts Argument seltsam. Niemand gibt den Namen der zweiten Klasse ein, sie lassen ihn von Intellisense für sie schreiben, aber dann dreht er sich um und behauptet, dass var besser ist, weil der Compiler / Intellisense es ausarbeitet. Sie können es nicht in beide Richtungen haben!
Dave
5
Das C # -Team steuert Intellisense nicht, sondern den Compiler. Auf jeden Fall ist das nicht das Hauptproblem. Ich glaube nicht, dass var die 100 Punkte beim Speichern des Tippens alleine gemacht hätte.
Dustman
@Dustman: var speichert das Tippen überhaupt nicht. Es bringt dich dazu, mehr zu schreiben!
Piotr Perak
53

Ich denke, die Verwendung von var sollte mit weise ausgewählten Variablennamen gekoppelt werden.

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

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 dies sogar noch besser.

Gleiches kann für andere Situationen gelten. Das ist ziemlich nutzlos:

var x = SaveFoo(foo);

... aber das macht Sinn:

var saveSucceeded = SaveFoo(foo);

Jeder für sich, denke ich. Ich habe dies getan, was einfach verrückt ist:

var f = (float)3;

Ich brauche eine Art 12-Stufen-Var-Programm. Mein Name ist Matt und ich (ab) benutze var.

Matt Hamilton
quelle
6
Nun, das einzige, was mit "var f = (float) 3;" ist, dass es "var f = 3f" oder "var f = 3.0 (verursachen mit einfacher Genauigkeit saugt) sein sollte".
MichaelGG
3
Heh yeah 3f oder 3.0 ist der richtige Weg! Wir Var Maniacs müssen zusammenhalten!
Matt Hamilton
27
Das eigentliche Problem in diesem ersten Beispiel ist "Liste", nicht "c". "Liste" von was ? "Liste" sollte in "Kunden" oder "customersWhoOweMoney" oder "currentCustomers" oder in etwas weitaus Beschreibenderes umbenannt werden. Und sobald Sie das haben, kann das "c" so bleiben, wie es ist, weil Sie bereits wissen, was es enthalten wird.
Ryan Lundy
4
Hallo Matt! Mein Name ist Kenny und ich bin ein Varaddict.
Kenny
var MattHamil = "Luke Skywalker"; // eine Tonne
rausgezogen
40

Wir haben das Ethos "Code für Menschen, nicht für Maschinen" übernommen, basierend auf der Annahme, dass Sie im Wartungsmodus mehrmals länger verbringen als bei Neuentwicklungen.

Für mich schließt dies das Argument aus, dass der Compiler "weiß", um welchen Typ es sich bei der Variablen handelt. Natürlich können Sie beim ersten Mal keinen ungültigen Code schreiben, da der Compiler das Kompilieren Ihres Codes verhindert, aber wenn der nächste Entwickler den Code liest In 6 Monaten müssen sie in der Lage sein, die korrekte oder falsche Funktion der Variablen abzuleiten und die Ursache der Probleme schnell zu identifizieren.

Somit,

var something = SomeMethod();

ist durch unsere Codierungsstandards verboten, aber in unserem Team wird Folgendes empfohlen, da dies die Lesbarkeit verbessert:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}
Dexter
quelle
4
Ich habe festgestellt, dass ("Code für Menschen, nicht für Maschinen") eine hervorragende Richtlinie ist. Das Befolgen dieser Richtlinien kann zu besserem Code führen und hilft, vorzeitige Optimierung zu vermeiden.
Thanatos
3
Ich bekomme keine var list = new KeyValuePair <string, double>? Für mich kann eine Liste mehr als nur eine Sache haben.
TTT
"Code für Menschen, nicht für Maschinen" - Amen.
user1068352
39

Es ist nicht schlecht, es ist eher eine stilistische Sache, die eher subjektiv ist. Es kann zu Inkonsistenzen kommen, wenn Sie var verwenden und wenn Sie dies nicht tun.

Ein weiterer besorgniserregender Fall: Im folgenden Aufruf können Sie nicht anhand des Codes erkennen, von welchem ​​Typ er zurückgegeben wurde CallMe:

var variable = CallMe();

Das ist meine Hauptbeschwerde gegen var.

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

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

BEARBEITEN : Das letzte Codebeispiel wurde basierend auf Julians Eingabe aktualisiert

Ion Todirel
quelle
3
Aber müssen Sie wirklich den Typ genau dort in dieser Zeile kennen? Sie wissen, dass CallMe etwas zurückgibt. Ist es nicht genug zu wissen, dass eine lokale Variable mit dem Namen variableerstellt wird? Sofern Sie Ihr Beispiel nicht erweitern, ist dies keine sehr solide Beschwerde, IMO.
Randolpho
2
Es geht nicht darum, nicht wortreich zu sein, es geht darum, den Compiler nicht den Syntaxzucker für Sie machen zu lassen. Bedenken Sie Folgendes : var getter ..., jetzt diesen Func <object> getter ..., mit dem zweiten, von dem Sie wissen, dass Sie keine Parameter angeben müssen und was er zurückgibt. Sie wissen von Anfang an, was zu tun ist, und können Entscheidungen schneller treffen, wenn Sie etwas entwerfen oder umgestalten. Es ist wichtiger, alle Informationen zur Hand zu haben als ein paar Zeichen mehr. Dies kann nur gewürdigt werden, wenn Sie mit viel Code arbeiten.
Ion Todirel
2
Da wir sowieso alle über Visual Studio sprechen, was ist die große Sache, wenn Sie Ihre Maus für eine Sekunde über die Variable bewegen und nur sehen, um welchen Typ es sich handelt? Viel besser als trotzdem zur Erklärung zu laufen.
Rubys
3
Generische Variablen- und Funktionsnamen ( variable, CallMe) sind schlechte Beispiele. Wenn CallMe()jedoch eine Funktion in einer Art "Telefonanwendung" var call = CallMe(); .... call.HangUp();wäre, wäre dies viel sinnvoller.
Danko Durbić
3
@Randolpho: "Was ist die große Sache, wenn Sie Ihre Maus für eine Sekunde über die Variable bewegen und nur sehen, um welchen Typ es sich handelt?" Dies erhöht den Wartungsaufwand um eine Zeit ... plus eine Sekunde ist nur die Schwebezeit, anstatt den Kontextwechsel zwischen Tastatur und Maus zu zählen. Ich weiß nichts über dich, aber ich arbeite mit einer Frist. Jedes Mal, wenn ich mit der Maus über eine Variable fahren muss, um herauszufinden, um welchen Typ es sich handelt, hätte ich besser ein Problem beheben können.
Powerlord
36

Var ist überhaupt keine Variante. Die Variable ist immer noch stark typisiert. Sie drücken lediglich keine Tasten, um dies zu erreichen. Sie können in Visual Studio mit der Maus darüber fahren, um den Typ anzuzeigen. Wenn Sie gedruckten Code lesen, müssen Sie möglicherweise ein wenig nachdenken, um herauszufinden, um welchen Typ es sich handelt. Es gibt jedoch nur eine Zeile, in der dies deklariert wird, und viele Zeilen, in denen es verwendet wird. Daher ist es immer noch der beste Weg, den Code einfacher zu befolgen, wenn Sie den Dingen anständige Namen geben.

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

Kate Gregory
quelle
6
+1, einzige zu beachtende Person, vardie nichts damit zu tun hat Variant.
user7116
27

Die wahrscheinlichste Zeit, die Sie dafür benötigen, ist für anonyme Typen (wo dies zu 100% erforderlich ist). aber es vermeidet auch Wiederholungen für die trivialen Fälle, und IMO macht die Linie klarer. Für eine einfache Initialisierung muss der Typ nicht zweimal angezeigt werden.

Zum Beispiel:

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

(Bitte bearbeiten Sie den hscroll oben nicht - es beweist irgendwie den Punkt !!!)

vs:

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

Es gibt jedoch Fälle, in denen dies irreführend ist und möglicherweise Fehler verursachen kann. Seien Sie vorsichtig, varwenn die ursprüngliche Variable und der initialisierte Typ nicht identisch sind. 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);
Marc Gravell
quelle
1
(Für Informationen können Sie ähnliche Probleme bei
allen
1
Stimmen Sie dem Teil nicht zu, dass Sie ihn nicht zweimal in derselben Zeile sehen möchten. Es ist möglich, dass Sie in Zukunft die Variable nach dem Deklarieren nicht direkt erstellen (z. B. in einem Wenn unterhalb der Definition), da möglicherweise nicht direkt klar ist, um welchen Typ es sich handelt. Die meisten Entwickler verwenden den Typ direkt am Zeilenanfang, insbesondere bei komplexem Code, bei dem das Lesen des Codes nicht erschwert werden soll.
Gertjan
@TheVillageIdiot - Ich habe Ihre Bearbeitung zurückgesetzt, weil bei dieser Gelegenheit der hscroll mit dem Punkt zusammenhängt ;-p
Marc Gravell
2
@Gertjan - mein Gehirn ist begrenzt; Wenn es komplex ist, möchte ich es nicht zweimal sehen und muss mit dem Vergleichen beginnen (Schnittstelle / Beton / usw.). Ich bin froh, es einmal zu sehen und denke, "als einer von ihnen getippt".
Marc Gravell
17

Ein spezieller Fall, in dem var schwierig ist: Offline-Codeüberprüfungen, insbesondere auf Papier.

Dafür können Sie sich nicht auf Mouse-Over verlassen.

Jon Limjap
quelle
17
Warum zum Teufel überprüfen Sie den Code auf Papier? Denken Sie an die Bäume! ;)
Dustman
8
Sie können das gleiche Problem haben, ohne var zu verwenden. Das Problem ist nicht var; Das Problem sind schlechte Variablennamen. Wenn Variablennamen gut ausgewählt sind, spielt die Verwendung von var keine Rolle.
Ryan Lundy
Ich habe einen Mann in meinem Team, der seinen eigenen Code überprüft und nach Fehlern sucht, indem er seinen Code druckt. Seine Wände sind mit Code bedeckt. Ich bin einmal hereingekommen und er hatte ein ganzes großes Whiteboard mit einer seiner Debugging-Übungen bedeckt. Es war wahrscheinlich ~ 10000 LOC
Beep Beep
Variablennamen allein lösen das Problem nur, wenn Sie zur ungarischen Notation zurückkehren, in der der Typ Teil des Namens ist.
Kevin Gale
17

Ich verstehe nicht, was die große Sache ist ..

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

Sie haben immer noch die volle Intelligenz für 'etwas' und für jeden zweideutigen Fall haben Sie Ihre Unit-Tests, oder? ( machst du? )

Es ist kein Varchar, es ist nicht dunkel und es ist sicherlich keine dynamische oder schwache Eingabe. Es stoppt Madden wie folgt:

List<somethinglongtypename> v = new List<somethinglongtypename>();

und Reduzieren dieser totalen Unordnung auf:

var v = new List<somethinglongtypename>();

Schön, nicht ganz so schön wie:

v = List<somethinglongtypename>();

Aber dafür ist Boo da .

Frep D-Oronge
quelle
Der Typ von 'etwas' ist für den Compiler sehr klar. Intern wird das "var" auf den Rückgabetyp von 'someMethod' gesetzt. Es ist für den Compiler klar, für die Entwickler, die an dem Projekt arbeiten, jedoch möglicherweise nicht klar. und Boo wächst schnell auf mir.
Stephenbayer
Nein, v = List<somethinglongtypename>();ist nicht noch schöner. Es ist wichtig zu unterscheiden, ob eine neue Variable eingeführt oder einer vorhandenen Variablen zugewiesen wird.
HighCommander4
Nun, wenn Sie zuvor im aktuellen Bereich 'v' zugewiesen haben, dann ist es die Zuordnung zu einem vorhandenen. Andernfalls wird die neue Variable 'v' zugewiesen. Einfach.
Frep D-Oronge
17

Wenn jemand das varSchlüsselwort verwendet, weil er den Typ nicht "herausfinden" möchte, ist dies definitiv der falsche Grund. Das varSchlüsselwort erstellt keine Variable mit einem dynamischen Typ, der Compiler muss den Typ noch kennen. Da die Variable immer einen bestimmten Typ hat, sollte der Typ nach Möglichkeit auch im Code ersichtlich sein.

Gute Gründe für die Verwendung des varSchlüsselworts sind zum Beispiel:

  • Wo es benötigt wird, dh um eine Referenz für einen anonymen Typ zu deklarieren.
  • Wo es den Code lesbarer macht, dh sich wiederholende Deklarationen entfernen.

Das Ausschreiben des Datentyps erleichtert häufig das Verfolgen des Codes. Es zeigt, welche Datentypen Sie verwenden, sodass Sie den Datentyp nicht herausfinden müssen, indem Sie zuerst herausfinden, was der Code tut.

Guffa
quelle
11

Angesichts der Leistungsfähigkeit von Intellisense bin ich mir nicht sicher, ob var schwerer zu lesen ist als Mitgliedsvariablen in einer Klasse oder lokale Variablen in einer Methode, die außerhalb des sichtbaren Bildschirmbereichs definiert sind.

Wenn Sie eine Codezeile wie haben

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Es ist viel einfacher oder schwerer zu lesen als:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();
Colin Desmond
quelle
Ich habe dies nicht wirklich in Betracht gezogen, da es aus der anderen Frage hervorgeht, dass es ein ziemlich starkes Argument für ein anderes Mal ist, es zu verwenden.
Finglas
Das war im Grunde der einzige Grund, warum sie es implementiert haben (abgesehen davon, dass sie anonyme Typen deklarieren konnten, aber sie hätten "var" zu einem speziellen Schlüsselwort machen können, das nur für anonyme Typen war.)
mqp
10

Ich denke, das Wichtigste bei VAR ist, es nur dort zu verwenden, wo es angebracht ist, dh wenn Sie Dinge in Linq tun, die es erleichtert (und wahrscheinlich in anderen Fällen).

Wenn Sie schon bekommen einen Typen für etwas in der dann sollten Sie sie verwenden - nicht so zu tun , ist einfach Faulheit (im Gegensatz zu kreativer Faulheit gegenüber, die im Allgemeinen gefördert werden soll - gute Programmierer oft sehr hart arbeiten , faul zu sein und könnte in Betracht gezogen werden die Quelle der Sache an erster Stelle).

Ein generelles Verbot ist genauso schlimm wie der Missbrauch des Konstrukts, aber es muss einen vernünftigen Codierungsstandard geben.

Die andere Sache, an die man sich erinnern sollte, ist, dass es keine VB- Typvariable ist , da es keine Typen ändern kann - es ist eine stark typisierte Variable, nur dass der Typ abgeleitet wird (weshalb es Leute gibt, die argumentieren, dass dies nicht unangemessen ist Verwenden Sie es beispielsweise in einem Foreach, aber ich würde aus Gründen der Lesbarkeit und Wartbarkeit nicht zustimmen.

Ich vermute, dieser wird rennen und rennen (-:

Murph

Murph
quelle
10

Sicher, intist einfach, aber wenn der Typ der Variablen ist IEnumerable<MyStupidLongNamedGenericClass<int, string>>, macht var die Dinge viel einfacher.

Blorgbeard ist raus
quelle
2
+1 dafür. intVersus varist etwas, worüber man sich streiten muss, aber mehrere verschachtelte generische Typen sind varein Glücksfall. Hier zerstört die wiederholte Verwendung des Typnamens die Lesbarkeit des Codes.
Chris Farmer
Dies ist absolut der falsche Grund für die Verwendung. Wenn Ihr Code einen verschachtelten generischen Typ verwendet, sollten Sie eine bestimmte benannte Klasse dafür ableiten. Zum Beispiel: class IntStringEnumerator : IEnumerable<MyStupidLongNamedGenericClass<int, string>>und verwenden Sie dann den neuen Namen. Das bereinigt den Code und beschreibt den Typ besser.
xxbbcc
Okay, aber mein Beispiel war nur Übertreibung. IntStringEnumerator i = new IntStringEnumerator()tippt immer noch zu viel.
Blorgbeard ist
9

Aus dem Beitrag zu diesem Thema bei CodingHorror gestohlen :


Leider haben Sie und alle anderen es ziemlich falsch verstanden. Ich stimme Ihnen zwar zu, dass Redundanz keine gute Sache ist, aber der bessere Weg, um dieses Problem zu lösen, wäre gewesen, etwa Folgendes zu tun:

MyObject m = new ();

Oder wenn Sie Parameter übergeben:

Person p = neu ("Vorname", "Nachname);

Bei der Erstellung eines neuen Objekts leitet der Compiler den Typ von links und nicht von rechts ab. Dies hat andere Vorteile gegenüber "var", da es auch in Felddeklarationen verwendet werden kann (es gibt auch einige andere Bereiche, in denen es ebenfalls nützlich sein könnte, aber ich werde hier nicht darauf eingehen).

Am Ende war es einfach nicht beabsichtigt, die Redundanz zu reduzieren. Versteh mich nicht falsch, "var" ist in C # für anonyme Typen / Projektionen SEHR wichtig, aber die Verwendung hier ist nur WEG (und das habe ich schon lange gesagt), da Sie den Typ verschleiern, der wird benutzt. Es ist zu oft, es zweimal eingeben zu müssen, aber es ist zu selten, es nullmal zu deklarieren.

Nicholas Paldino .NET / C # MVP am 20. Juni 2008 um 08:00 Uhr


Ich denke, wenn Ihr Hauptanliegen darin besteht, weniger tippen zu müssen, dann gibt es kein Argument, das Sie davon abhält, es zu verwenden.

Wenn Sie jemals nur die Person sein werden, die sich Ihren Code ansieht, wen interessiert das dann? Ansonsten in einem Fall wie diesem:

var people = Managers.People

Es ist in Ordnung, aber in einem Fall wie diesem:

var fc = Factory.Run();

Es schließt alle unmittelbaren Typabzüge kurz, die mein Gehirn aus dem 'Englisch' des Codes bilden könnte.

Andernfalls verwenden Sie einfach Ihr bestes Urteilsvermögen und programmieren Sie "Höflichkeit" gegenüber anderen, die möglicherweise an Ihrem Projekt arbeiten müssen.

Rostow
quelle
4
Ihre obigen Beispiele sind kein Argument dafür, var nicht zu verwenden. Sie sind ein Argument für die Verwendung guter beschreibender Variablennamen. Wenn Sie anstelle von [var fc = Factory.Run ();] [bool fc = Factory.Run ();] hätten, würde der Code nicht klarer werden.
Ryan Lundy
9

Die Verwendung varanstelle eines expliziten Typs erleichtert die Umgestaltung erheblich (daher muss ich den vorherigen Postern widersprechen, die bedeuteten, dass es keinen Unterschied machte oder es sich lediglich um "syntaktischen Zucker" handelte).

Sie können den Rückgabetyp Ihrer Methoden ändern, ohne jede Datei zu ändern, in der diese Methode aufgerufen wird. Vorstellen

...
List<MyClass> SomeMethod() { ... }
...

welches wie verwendet wird

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

Wenn Sie einen Refactor SomeMethod()für die Rückgabe eines IEnumerable<MySecondClass>erstellen möchten, müssen Sie die Variablendeklaration ändern (auch innerhalb desforeach ) an jeder Stelle Sie die Methode verwendet haben.

Wenn du schreibst

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

Stattdessen müssen Sie es nicht ändern.

MartinStettner
quelle
stimmte zu - fragte sich, warum dieser nette Nebeneffekt nicht so oft angepriesen wird wie einige der anderen, subjektiveren Profis in den populäreren Antworten.
Fieldingmellish
Es ist mir heute passiert. Ich habe eine Factory-Klasse, die die Übereinstimmung einer MainMenu-Klasse zurückgibt. Heute habe ich ein MainMenu2 mit der gleichen Oberfläche von MainMenu erstellt. Ich habe meinen gesamten App-Code nach der Änderung unberührt!
Marco Staffoli
8

@aku: Ein Beispiel sind Codeüberprüfungen. Ein weiteres Beispiel sind Refactoring-Szenarien.

Grundsätzlich möchte ich nicht mit meiner Maus auf Typjagd gehen. Es ist möglicherweise nicht verfügbar.

erlando
quelle
2
Es ist interessant, dass Sie das sagen, weil var das Refactoring vereinfachen kann. Wenn Sie var verwendet haben, müssen Sie nicht. Jetzt können Sie sich immer auf die Refactoring-Tools der IDE verlassen, aber Sie wissen, Sie können sich auch immer auf die IDE für den Typ verlassen :)
Fred
8

Es ist Geschmackssache. All diese Aufregung um den Typ einer Variablen verschwindet, wenn Sie sich an dynamisch typisierte Sprachen gewöhnen. Das heißt, wenn Sie jemals anfangen, sie zu mögen (ich bin nicht sicher, ob jeder kann, aber ich tue es).

C # varist ziemlich cool, da es wie dynamisches Tippen aussieht , aber tatsächlich statisches Tippen ist - der Compiler erzwingt die korrekte Verwendung.

Der Typ Ihrer Variablen ist nicht wirklich so wichtig (dies wurde bereits gesagt). Es sollte relativ klar aus dem Kontext (seinen Interaktionen mit anderen Variablen und Methoden) und seinem Namen hervorgehen - erwarten Sie nicht, dass customerList eine int...

Ich warte immer noch darauf zu sehen, was mein Chef von dieser Angelegenheit hält - ich habe eine Decke bekommen, um neue Konstrukte in 3.5 zu verwenden, aber was werden wir gegen die Wartung tun?

Daren Thomas
quelle
7

In Ihrem Vergleich zwischen IEnumerable<int>und IEnumerable<double>Sie müssen sich keine Sorgen machen - wenn Sie den falschen Typ übergeben, wird Ihr Code sowieso nicht kompiliert.

Es gibt keine Sorge über Typsicherheit, da varist nicht dynamisch. Es ist nur Compiler-Magie und jede Art von unsicheren Aufrufen, die Sie tätigen, wird abgefangen.

Var wird für Linq unbedingt benötigt:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

Schauen Sie sich nun anonEnumeration in Intellisense an und es wird ungefähr so ​​aussehenIEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

Der C # -Compiler ist ziemlich clever - separat generierte Anontypen haben denselben generierten Typ, wenn ihre Eigenschaften übereinstimmen.

Abgesehen davon ist es sinnvoll, varüberall dort, wo der Kontext klar ist, zu verwenden, solange Sie Intellisense haben .

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;
Keith
quelle
Bitte loswerden, IQueriable<T>bevor Sie iterieren: anonEnumeration.ToList();
David Diez
@ DavidDiez könnten Sie umformulieren? Ihre Aussage macht keinen Sinn. Keiner meiner Code-Schnipsel referenziert IQueryableoder.ToList()
Keith
var anonEnumeration = from post in AllPosts() where post.Date > oldDate let author = GetAuthor( post.AuthorId ) select new { PostName = post.Name, post.Date, AuthorName = author.Name };gibt kein zurück IQueriable<T>?
David Diez
1
@DavidDiez es kommt darauf an, was AllPosts()zurückkommt - der Fragesteller bezieht sich darauf, List<T>also habe ich das angenommen. In diesem Fall ist das Ergebnis anonEnumerationvom Typ IEnumerable<'a>. Wenn nun AllPosts()kehrt IQueryable<T>stattdessen dann anonEnumerationwird werden IQueryable<'a>(Anmerkung nicht iin Abfragbare) - aber in diesem Fall mein Code noch da funktioniert IQueryable<T>implementiert IEnumerable<T>. Es gibt hier eine Menge besserer Fragen und Antworten zu den Unterscheidungen zwischen ihnen - hier ist mein Fall 'aanonym und varermöglicht es Ihnen, ihn einer statisch typisierten Variablen zuzuweisen.
Keith
Ohh, ich verstehe, danke, dass IQueryable<T>du es erklärt hast :) Mein Kommentar war, weil das Iterieren von keine gute Praxis ist, weil du in jeder Iteration eine Leseanweisung in DB machst. Seien Sie sicher, *.ToList() IQueryable<T>bevor Sie sie wiederholen
David Diez
7

Ich denke, es hängt von Ihrer Perspektive ab. Ich persönlich hatte nie Schwierigkeiten, einen Code wegen var"Missbrauchs" zu verstehen , und meine Mitarbeiter und ich verwenden ihn überall ziemlich häufig. (Ich stimme zu, dass Intellisense in dieser Hinsicht eine große Hilfe ist.) Ich begrüße es als einen Weg, sich wiederholende Kruft zu entfernen.

Immerhin, wenn Aussagen wie

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

Wäre es wirklich so unmöglich, damit umzugehen, würde niemand dynamisch getippte Sprachen verwenden.

mqp
quelle
Vermutlich in .Net 4, wo dynamische Typen üblich sind, wird dies wichtiger?
Colin Desmond
2
Im Gegenteil, wenn Sie jetzt durch "var" verwirrt sind, würde ich erwarten, dass Sie zusätzlich durch "dynamic" verwirrt werden. Gott bewahre, dass irgendjemand jemals eine Dynamik deklariert und dann mit "var" darauf
verweist
Ich meinte so etwas wie dynamisches d = 52; var x = d; das sollte in Ordnung sein.
mqp
7

Ich benutze var nur, wenn klar ist, welcher Typ verwendet wird.

Zum Beispiel würde ich in diesem Fall var verwenden, da Sie sofort sehen können, dass x vom Typ "MyClass" ist:

var x = new MyClass();

In solchen Fällen würde ich var NICHT verwenden, da Sie die Maus über den Code ziehen und in der QuickInfo nachsehen müssen, welcher Typ MyFunction zurückgibt:

var x = MyClass.MyFunction();

Insbesondere verwende ich var nie in Fällen, in denen die rechte Seite nicht einmal eine Methode ist, sondern nur ein Wert:

var x = 5;

(weil der Compiler nicht wissen kann, ob ich ein Byte, Short, Int oder was auch immer will)

Christian Specht
quelle
Wenn die rechte Seite nicht klar genug ist, um die Verwendung zu rechtfertigen var, dann varist das nicht das Problem: Die rechte Seite ist das Problem. Es ist nicht beschreibend genug . Customer c = GetContext()ist noch unklar und nicht besser als zu verwenden var.
JulianR
6

Für mich zeigt die Abneigung gegen var, warum Zweisprachigkeit in .NET wichtig ist. Für diejenigen C # -Programmierer, die auch VB .NET ausgeführt haben, liegen die Vorteile von varintuitiv auf der Hand. Die Standard-C # -Deklaration von:

List<string> whatever = new List<string>();

entspricht in VB .NET der folgenden Eingabe:

Dim whatever As List(Of String) = New List(Of String)

In VB .NET macht das allerdings niemand. Es wäre dumm, denn seit der ersten Version von .NET können Sie dies tun ...

Dim whatever As New List(Of String)

... wodurch die Variable erstellt und alles in einer einigermaßen kompakten Zeile initialisiert wird. Ah, aber was ist, wenn Sie eine wollen IList<string>, keine List<string>? In VB .NET bedeutet dies, dass Sie Folgendes tun müssen:

Dim whatever As IList(Of String) = New List(Of String)

Genau wie Sie es in C # tun müssten und offensichtlich nicht verwenden könnten varfür:

IList<string> whatever = new List<string>();

Wenn Sie benötigen die Art , etwas anderes zu sein, kann es sein. Eines der Grundprinzipien einer guten Programmierung ist jedoch die Reduzierung der Redundanz, und genau das tut var.

Ryan Lundy
quelle
1
Lustigerweise erwähnen Sie Zweisprachigkeit als etwas, das die Verwendung von var fördert. Mein Antagonismus gegenüber dem Schlüsselwort var beruht direkt auf meiner fließenden Javascript-Sprache! :)
urig
varin C # hat überhaupt keine Verbindung mit varin JavaScript. Eine vardeklarierte Variable in C # ist stark typisiert.
Ryan Lundy
6

Verwenden Sie es für anonyme Typen - dafür ist es da. Alles andere ist zu weit verbreitet. Wie viele Leute, die mit C aufgewachsen sind, bin ich es gewohnt, links in der Erklärung nach dem Typ zu suchen. Ich schaue nicht auf die rechte Seite, es sei denn, ich muss. Wenn varich für eine alte Erklärung verwende, mache ich das die ganze Zeit, was mir persönlich unangenehm ist.

Diejenigen, die sagen: "Es spielt keine Rolle, verwenden Sie, womit Sie zufrieden sind", sehen nicht das ganze Bild. Jeder wird irgendwann den Code anderer Leute aufgreifen und sich mit den Entscheidungen befassen müssen, die er zum Zeitpunkt des Schreibens getroffen hat. Es ist schon schlimm genug, sich mit radikal anderen Namenskonventionen oder - den klassischen Gripe - Bracing-Stilen auseinandersetzen zu müssen, ohne das Ganze ' varoder nicht' in die Mischung aufzunehmen. Der schlimmste Fall wird sein, wenn ein Programmierer nicht verwendet hat, varund dann kommt ein Betreuer, der es liebt, und erweitert den Code, der es verwendet. Jetzt hast du also ein unheiliges Durcheinander.

Standards sind eine gute Sache, gerade weil sie bedeuten, dass Sie mit viel größerer Wahrscheinlichkeit zufälligen Code erfassen und schnell verarbeiten können. Je mehr Dinge anders sind, desto schwieriger wird es. Und die Umstellung auf den Stil "überall überall" macht einen großen Unterschied Unterschied.

Es macht mir nichts aus, dynamisch zu tippen, und es macht mir nichts aus, das Tippen zu implizieren - in Sprachen, die für sie entwickelt wurden. Ich mag Python sehr. Aber C # wurde als statisch explizit typisierte Sprache entworfen und so sollte es auch bleiben. Die Regeln für anonyme Typen zu brechen war schon schlimm genug; Es ist etwas, mit dem ich nicht zufrieden bin, wenn die Leute das noch weiter gehen lassen und die Redewendungen der Sprache noch mehr brechen. Jetzt, wo der Geist aus der Flasche ist, wird er nie wieder hineingehen. C # wird in Lager balkanisiert. Nicht gut.

Neil Hewitt
quelle
7
Beeindruckend. Das Ignorieren aller bisher in diesem Thread vorgebrachten Argumente und das Zurücksetzen der gesamten Diskussion ist ein ziemlicher Erfolg.
Konrad Rudolph
Diese 100% beschreiben, wie ich über 'var' denke, insbesondere unter dem Gesichtspunkt, jemand anderen Code aufzunehmen. Die Verwendung von var verändert die vorliegende Aufgabe radikal, wenn sie durchgehend verschmutzt ist. +1
Simon
6

Während des Testens habe ich oft folgenden Code:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

Jetzt möchte ich manchmal sehen, was SomeOtherThing selbst enthält. SomeOtherThing ist nicht derselbe Typ, den CallMethod () zurückgibt. Da ich var verwende, ändere ich Folgendes:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

dazu:

var something = myObject.SomeProperty.SomeOtherThing;

Ohne var müsste ich auch den deklarierten Typ auf der linken Seite weiter ändern. Ich weiß, dass es geringfügig ist, aber es ist äußerst praktisch.

BKostenlos
quelle
6

Für Liebhaber, die denken, dass sie varZeit sparen, sind weniger Tastenanschläge erforderlich, um Folgendes einzugeben :

StringBuilder sb = new StringBuilder();

als

var sb = new StringBuilder();

Zähle sie, wenn du mir nicht glaubst ...

19 gegen 21

Ich werde erklären, ob ich muss, aber versuchen Sie es einfach ... (Abhängig vom aktuellen Status Ihres Intellisense müssen Sie möglicherweise für jeden ein paar mehr eingeben.)

Und es gilt für jeden Typ, den Sie sich vorstellen können !!

Mein persönliches Gefühl ist, dass var niemals verwendet werden sollte, außer wenn der Typ nicht bekannt ist, da dies die Lesbarkeit der Erkennung im Code verringert. Das Gehirn braucht länger, um den Typ zu erkennen, als eine vollständige Linie. Oldtimer, die Maschinencode und Bits verstehen, wissen genau, wovon ich spreche. Das Gehirn arbeitet parallel und wenn Sie var verwenden, zwingen Sie es, seine Eingabe zu serialisieren. Warum sollte jemand sein Gehirn härter arbeiten lassen wollen? Dafür sind Computer da.

Wray Smallwood
quelle
Ich finde die Wiederholung von stringBuilder sb = new StringBuilder () chaotisch und länger zu erkennen. Es ist extra Lärm. Das Problem ist, zu bestimmen, was zusätzliche intellektuelle Anstrengungen zum Verstehen von Code bedeutet und was nicht, ist ziemlich subjektiv!
ljs
"var sollte niemals verwendet werden, außer wenn der Typ nicht bekannt ist ..." - Sie können den Typ IMMER kennen, ebenso wie der Compiler. Dies ist keine dynamische Typisierung, sondern lässt den Compiler nur den Typ für Sie bestimmen. Aber der Typ ist niemals unbekannt.
Gabriel Magana
5

Ich teile var überall auf, die einzigen fragwürdigen Orte für mich sind interne Kurztypen, zB ziehe ich es int i = 3;vorvar i = 3;

robi-y
quelle
5

Mit dem Code, den ich gestern geschrieben habe, kann es die Dinge sicherlich einfacher machen:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

Dies wäre ohne sehr ausführlich gewesen var.

Nachtrag: Ein wenig Zeit mit einer Sprache mit realer Typinferenz (z. B. F #) zeigt, wie gut Compiler darin sind, die Art der Ausdrücke richtig zu machen. Es hat sicherlich bedeutet, dass ich dazu neige, varso viel wie möglich zu verwenden, und die Verwendung eines expliziten Typs zeigt jetzt an, dass die Variable nicht vom Typ des initialisierenden Ausdrucks ist.

Richard
quelle
Ja, Compiler sind schlauer als wir, überwinde es!
Benjol