Warum möchte ReSharper 'var' für alles verwenden?

214

Ich habe gerade angefangen, ReSharper mit Visual Studio zu verwenden (nach den vielen Empfehlungen zu SO). Zum Ausprobieren habe ich ein aktuelles ASP.NET MVC-Projekt geöffnet. Eines der ersten und häufigsten Dinge, die mir aufgefallen sind, ist, die meisten / alle meine expliziten Erklärungen varstattdessen zu ändern . Beispielsweise:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

und so weiter, auch mit einfachen Typen wie int, boolusw.

Warum wird dies empfohlen? Ich komme nicht aus der Informatik oder dem .NET-Hintergrund, da ich kürzlich in die .NET-Entwicklung "hineingefallen" bin, daher würde ich gerne verstehen, was los ist und ob es von Nutzen ist oder nicht.

Chris
quelle
27
Ich habe eine Weile darüber nachgedacht und bin zu dem Schluss gekommen, dass ich immer verwenden sollte var, auch wenn der Typ überhaupt nicht offensichtlich ist! der Grund ist , weil es zwingt mich am meisten beschreibenden Namen zu wählen , ich kann kommen und letztlich macht , dass der Code viel, viel besser lesbar. Letztendlich hilft es auch, die Logik von der Implementierung zu trennen. Das ist natürlich nur meine Meinung, ich hoffe es würde jemandem helfen;).
MasterMastic

Antworten:

189

Ein Grund ist die verbesserte Lesbarkeit. Welches ist besser?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

oder

var dictionary = new Dictionary<int, MyLongNamedObject>();
Mark Sherretta
quelle
260
Ich würde den ersten sagen. Einfacher zu sehen, was los ist!
Mongus Pong
104
Fungus: Gefällt dir Redundanter Text Redundanter Text? : D
Mark Simpson
73
Explizit zu sein ist meiner Meinung nach klarer. Die Verwendung von var zu viel verursacht in einigen Szenarien Kopfschmerzen.
user1231231412
172
Ich hasse es, wenn Entwickler varfür alles verwenden - ich mache viele, viele Codeüberprüfungen mit TFS (webbasierte Unterschiede) und es macht meine Arbeit extrem schwierig: dh var items = GetSomeItems();vs IDataReader dr = GetSomeItems();Fehlende Verwendung von Anweisungen für beide, aber für mich leichter zu fangen, wenn ich IDataReadervs verwende var.
Chris Gessler
17
Wenn Sie ein guter Entwickler sind, der guten Code schreibt, und eine Bibliothek wie Resharper verwenden, müssen Sie den expliziten Typ, mit dem Sie sich befassen, nicht kennen. Genau wie wenn Sie Schnittstellen verwenden, um einen Vertrag zu deklarieren, aber keine konkrete Klasse, können Sie mit var sagen, dass es Ihnen egal ist, was der Rückgabetyp ist, Sie kümmern sich nur darum, was er tut, und verwenden benannte Variablen Mit Intelli-Sense & Resharper / VS-Helfern (wie STRG + KLICK, um zur Definition zu navigieren) gelangen Sie zu 99% dorthin. Darüber hinaus bedeutet die Verwendung von var, dass ich meine Codebasis nicht neu schreiben muss, wenn ich einen Methodenrückgabetyp ändere.
Joshua Barker
286

Was ReSharper vorschlägt, ist eine deutliche Überbeanspruchung des Schlüsselworts var. Sie können es verwenden, wenn der Typ offensichtlich ist:

var obj = new SomeObject();

Wenn der Typ nicht offensichtlich ist, sollten Sie ihn lieber aufschreiben:

SomeObject obj = DB.SomeClass.GetObject(42);
Guffa
quelle
36
Wenn Devils Advocate nicht aus der Methode oder dem Variablennamen hervorgeht, deutet dies möglicherweise auf ein Problem mit der Benennung von mehr als einer übermäßigen Verwendung von var hin. Grundsätzlich stimme ich jedoch zu, dass var nur verwendet werden sollte, wenn es die Klarheit nicht beseitigt.
Matt Briggs
33
In diesem Fall würde ich lieber bessere Variablennamen verwenden. Sie schlagen im Grunde vor, dass wir nachsehen, wo die Variable definiert ist, um den Typ herauszufinden. Ich schlage vor, dass wir die Variablen besser benennen, damit wir den Zweck der Variablen sofort kennen.
Jaco Pretorius
18
@Jaco: +1, aber es ist erwähnenswert, dass Informationen zum Typ nicht in einem Variablennamen empfohlen werden. Beispielsweise wird die ungarische Notation nicht als gute Praxis angesehen.
Roman Boiko
8
Ob die Standardeinstellungen von ReSharper zu häufig verwendet werden, ist Ansichtssache varund nicht "eindeutig" die eine oder andere Sache. Ich ziehe es vor, keine Dinge einzugeben, die der Compiler selbst herausfinden kann. Ich mag Inferenz vom Typ C # und wünschte oft, sie wäre so gut wie Inferenz vom Typ F #. Wenn ich könnte, würde ich explizite Typen aus Methodenparametern und Rückgabetypen weglassen, wie es in F # üblich ist. Natürlich sind sich nicht alle einig.
Joel Mueller
15
@AnonymousType: Sie verpassen immer noch den Punkt. Sie sagten, dass Methodennamen immer die Absicht der Methode widerspiegeln sollten, aber selbst wenn dies der Fall ist, bedeutet dies nicht, dass der Name den Typ des Rückgabewerts angibt. Die Methode zum Lesen von einem StreamObjekt heißt beispielsweise Readnicht ReadAndReturnNumberOfBytesAsInt32.
Guffa
99

Ich persönlich ziehe es vor, diesen Vorschlag auszuschalten. Die Verwendung varkann häufig die Lesbarkeit verbessern. Aber wie Sie bereits erwähnt haben, wird es manchmal reduziert (bei einfachen Typen oder wenn der resultierende Typ dunkel ist ).

Ich wähle lieber, wann ich benutze varund wann nicht. Aber das bin nur ich.

Bryan Menard
quelle
11
Ich dachte, ReSharper sollte ziemlich schlau sein. Sollte es nicht klug genug sein zu wissen, wann der resultierende Typ offensichtlich ist (z. B. irgendetwas mit dem neuen Schlüsselwort) und wann er nicht offensichtlich ist?
DisgruntledGoat
3
Nun, ich kenne die Besonderheiten des Features nicht, aber ich weiß, dass ich von der Menge an Vorschlägen überwältigt war. Und ich benutze auch varziemlich oft.
Bryan Menard
5
Ich habe herausgefunden, dass Sie, wenn Sie immer var verwenden (wie von resharper vorgeschlagen), gezwungen sind, Ihre Variablen richtig zu benennen.
Sauleil
Können Sie den Vorschlag deaktivieren?
Chris S
@AngeDeLaMort: Der Punkt ist, dass es Sie zwingt, Namen zu verwenden, die unangemessen sind, z var methodXYResultIntArray. Das ist gegen alle Kodierungsstandards und weniger prägnant als int[] methodXYResult. Wenn Sie byte[]in Zukunft eine von der Methode zurückgeben möchten, sind alle Ihre Variablennamen falsch. Mit expliziten Typen können Sie dies sehr einfach umgestalten. Es gibt Gründe zu verwenden var, zB mit a Dictionary<string, List<SomeType<int>>>. Wenn der vollständige Typname jedoch nicht zu lang ist und Sie keinen Resharper newauf der rechten Seite (oder eine explizite Besetzung) verwenden, sollte dies nicht empfohlen werden.
Tim Schmelter
69

varkann die Lesbarkeit des Codes verbessern und gleichzeitig das sofortige Verständnis des Codes verringern. Trotzdem kann es die Lesbarkeit des Codes für andere Situationen beeinträchtigen. Manchmal ist die Verwendung neutral. Das Maß für die Lesbarkeit zum Verständnis ist nicht proportional, sondern hängt von der Situation ab. Manchmal werden beide zusammen erhöht oder verringert.

Der Faktor ist, worauf varangewendet wird und wie gut das Ziel die sofortige Verschleierung seines Datentyps für den Leser unterstützt oder ob seine Typinformationen benötigt werden, um den vorliegenden Programmteil zu verstehen.

Beispielsweise kann eine schlechte Benennung dazu führen, vardass das Codeverständnis abnimmt. Dies ist jedoch nicht vardie Schuld:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

Manchmal ist es nicht sinnvoll, varfür einfache Datentypen zu verwenden, wenn Code in Abwesenheit besser lesbar ist:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

Manchmal varkann es nützlich sein, Datentypinformationen auszublenden, bei denen Sie nicht unbedingt die Komplexität von:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

Sie müssen verwenden, varwenn ein anonymer Typ vorhanden ist, da kein Typname zum Aufrufen vorhanden ist:

var o = new { Num=3, Name="" };

Wenn Visual Studio Intellisense trotz allem Typinformationen bereitstellt var, müssen Sie sich weniger auf Ihr Verständnis durch striktes Lesen des Codes ohne Hilfe verlassen. Es ist wahrscheinlich ratsam anzunehmen, dass nicht jeder Intellisense hat oder verwendet.

Zusammenfassend würde ich anhand der obigen Beispiele vorschlagen, dass die Anwendung von Carte Blanche varkeine gute Idee ist, da die meisten Dinge am besten in Maßen und basierend auf den hier gezeigten Umständen erledigt werden.

Warum verwendet Resharper es standardmäßig überall? Ich würde es zur Vereinfachung vorschlagen, da es die Nuancen von Situationen nicht analysieren kann, um zu entscheiden, wann es am besten nicht verwendet werden soll.

John K.
quelle
5
IMHO Ihre Beispiele sind eigentlich gute Gründe zu verwenden var, es wird Sie zwingen, anständige Methodennamen zu schreiben. GetNumber() -but what type?- Nun, warum kümmert es dich? Wenn es so wichtig ist zu wissen, rufen Sie die Methode auf GetNumberAsDouble(), dann ist es genauso klar und funktioniert, wenn Sie eine Methode zurückgeben stringund eine zurückgeben double.
nicodemus13
10
@ nicodemus13 Sie wissen im Allgemeinen, wann Sie sich für den Rückgabetyp einer Funktion interessieren, wenn Sie den Rückgabewert tatsächlich verwenden , anstatt die Funktion selbst zu schreiben. Ihr vorgeschlagenes Namensschema kann zu Missbrauch wie GetResultsAsIEnumerableOfDouble führen. Es verschiebt lediglich die Typinformationen, die Sie von der linken Seite einer Zuweisung entfernt haben, indem Sie var verwenden, auf die rechte Seite der Zuweisung.
Eric
var value2 = Math.Abs ​​(-3); // Offensichtlich ein numerischer Datentyp. Es tut mir leid, dass ich in dieser
Frage überhaupt nicht
var kann auch zu subtilen logischen Fehlern führen wie: var counter = "0"; wenn Sie eine ganze Zahl wollen.
Alaniane
42

In ReSharper (8.02, aber wahrscheinlich auch in anderen Versionen) kann die Option für den Vorschlag "Implizit typisierte lokale Variablendeklaration verwenden" an Ihre Präferenz angepasst werden, indem Sie zuerst das Optionsmenü für ReSharper öffnen:

Menü "ReSharper-Optionen"

Dann unter "Code Inspection" durch Anpassen des "Inspection Severity" Ihrer gewählten Sprache, in meinem Fall c #:

Deaktivieren Sie den Vorschlag für implizit typisierte lokale Variablen

Wie Sie sehen, gibt es Optionen zum Anpassen aller Vorschläge von ReSharper. Hoffe, das hilft jemandem wie mir, der bereits eine 'var'-Nutzungsstrategie hat und nur möchte, dass ReSharper diese respektiert :)

Erikest
quelle
Dies beantwortet eine andere Frage, die überhaupt nicht gestellt wurde.
Carles Alcolea
9
Aber es ist relevant für viele, die danach suchen, wenn sie hierher kommen. +1
Ori Nachum
24

Ich bin überrascht, dass niemand erwähnt hat, dass es auch einfacher ist, den Typ des instanziierten Objekts zu ändern, weil

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

ist eine Form der Wiederholung . Wenn ich AVeryLongTypeNamein eine der abgeleiteten Klassen wechseln möchte , muss ich dies bei Verwendung nur einmal ändern varund kann weiterhin auf Methoden der untergeordneten Klassen zugreifen.

Abgesehen davon ist die verbesserte Lesbarkeit ein wichtiger Punkt, aber wie andere sagten, sollte var nicht überbeansprucht werden, daher denke ich, dass es absolut in Ordnung ist, den Hinweis in Resharper auszuschalten.

Philipp
quelle
Sehr nützlich, wenn Factory-Methoden statt "neu"
aufgerufen werden
Wenn Sie beim ersten Schreiben des Codes 'MyClass' verwenden müssen und es funktioniert, funktioniert es. Wenn Sie es ändern müssen, müssen Sie es überall ändern, insbesondere wenn Schnittstellen beteiligt sind. Code sollte nicht wie ein Aufsatz behandelt werden, er sollte semantisch und gut definiert sein.
Piotr Kula
24

Bei 'var' geht es darum, klar zu sein

Die Hauptdebatte darüber, ob das varSchlüsselwort verwendet werden soll oder nicht, besteht darin, wie lesbar der Code für Sie und andere Entwickler ist.

Als ob Sie eine Geschichte schreiben würden, gibt es keine endgültige richtige Antwort. Aber schauen wir uns einige Beispiele dafür im Klartext an.

Jake sagte Hallo zu Bill. Er mochte ihn nicht, also drehte er sich um und ging in die andere Richtung.

Wer ist den anderen Weg gegangen? Jake oder Bill? In diesem Fall entspricht die Verwendung der Namen "Jake" und "Bill" der Verwendung des Typnamens. Und "Er" und "Ihn" ist wie das Verwenden des varSchlüsselworts. In diesem Fall kann es hilfreich sein, genauer zu sein. Das Folgende ist zum Beispiel viel klarer.

Jake sagte Hallo zu Bill. Jake mochte Bill nicht, also drehte er sich um und ging in die andere Richtung.

In diesem Fall machte eine genauere Darstellung den Satz klarer. Aber das wird nicht immer der Fall sein. In einigen Fällen ist es schwieriger zu lesen, wenn man spezifisch ist.

Bill mag Bücher, also ging Bill in die Bibliothek und Bill holte ein Buch heraus, das Bill immer gefallen hat.

In diesem Fall wäre es einfacher, den Satz zu lesen, wenn wir "er" verwenden und in einigen Fällen seinen Namen alle zusammen weglassen würden, was der Verwendung des varSchlüsselworts entspricht.

Bill mag Bücher, also ging er in die Bibliothek und holte ein Buch heraus, das er immer gemocht hat.

Diese Beispiele decken den Kern ab, aber sie erzählen nicht die ganze Geschichte. In diesen Beispielen gab es nur einen Weg, sich auf die Person zu beziehen. Entweder durch Verwendung ihres Namens oder durch Verwendung eines allgemeineren Begriffs wie "er" und "ihn".

Im Fall von Code haben wir drei Möglichkeiten, um Klarheit zu schaffen. Der Typ, der Variablenname und die Zuordnung. Nehmen Sie zum Beispiel diese Codezeile:

Person p = GetPerson();

Es stellt sich nun die Frage, ob in dieser Codezeile genügend Informationen enthalten sind, um herauszufinden, was los ist.

Was ist mit der folgenden Codezeile? Würdest du noch wissen, was pin diesem Fall bedeutet:

var p = GetPerson();

Wie wäre es jetzt:

var p = Get();

Oder jetzt:

var person = Get();

Oder dieses:

var t = GetPerson();

Oder dieses:

var u = Person.Get();

Ob das Schlüsselwort varin einem bestimmten Szenario funktioniert, hängt stark vom Kontext des Codes ab, z. B. davon, wie die Variablen, Klassen und Methoden benannt werden. Dies hängt auch von der Komplexität des Codes und dem Rest des ihn umgebenden Codes ab.

Persönlich verwende ich gerne das varSchlüsselwort, das für mich die meiste Zeit umfassender ist. Aber ich neige auch dazu, meine Variablen nach dem Typ zu benennen, damit ich nicht wirklich Informationen verliere.

Das heißt, manchmal, abhängig vom Kontext, in dem ich Ausnahmen mache, ist dies die Natur von allem Komplexen, und Software ist nichts, wenn nicht komplex.

Luis Perez
quelle
1
Diese Antwort gefällt mir am besten, weil ich nichts dagegen habe var, solange ich weiß, was es ist, während ich diese eine Zeile lese. Wenn ich keine Ahnung habe, welche Methode eine andere Lösung mit einem anderen Domänenmodell zurückgibt, habe ich diesen Typ lieber explizit definiert, um das Lesen zu vereinfachen. +1
Piotr Kula
In all Ihren Fällen, in denen der zurückgegebene Typ nicht ersichtlich ist, sollten Sie var nicht verwenden, da Sie jetzt nützliche Informationen weglassen.
rollt
18

Ich mochte das auch nicht.

Ich möchte nicht, dass dies zu einer Debatte über die Verwendung von wird var, es hat seine Verwendung, sollte aber nicht überall verwendet werden.

Das Wichtigste ist, dass ReSharper nach den von Ihnen gewünschten Codierungsstandards konfiguriert ist.

Edit: ReSharper und var

LiamB
quelle
13
Nach ungefähr einem Jahr Widerstand benutze ich jetzt so ziemlich immer var.
LiamB
15

Ich sehe viele richtige Antworten, aber es fehlt die vollständige.

Es ist wahr, dass ReSharper varstandardmäßig überbeansprucht wird. Ich denke, die meisten Leute würden dem zustimmen. Es ist auch einfacher zu lesen, wann vares verwendet wird, und der Typ ist offensichtlich, z. B. wenn Sie eine newAnweisung verwenden. Ich habe einen Beitrag gesehen, in dem gezeigt wurde, wie der Schweregrad der Inspektion aktualisiert wird, um nur Hinweise für die Verwendung von anzuzeigen var.

Ich hatte versucht, zuerst andere Beiträge zu kommentieren, um hinzuzufügen, wo diese gesetzt werden sollen, hatte aber nicht den Ruf dafür. Anscheinend hatte ich auch nicht den Ruf, meinen Screenshot der Einstellungen zu veröffentlichen.

Ich werde erklären, wie man dorthin kommt.

In Visual Studio> Hauptmenü> Resharper> Optionen> Codebearbeitung> C #> Codestil> Var-Verwendung in Deklarationen

  • Für integrierte Typen Verwenden Sie einen expliziten Typ
  • Für einfache Typen Verwenden Sie 'var', wenn dies offensichtlich ist
  • Anderswo Use'var '

Geben Sie hier die Bildbeschreibung ein

ReSharper-Hilfedokumentation: Codesyntaxstil: Implizite / Explizite Typisierung (Schlüsselwort 'var') - Konfigurieren Sie die Einstellungen für die Verwendung des Schlüsselworts 'var'

Nathan Kovac
quelle
Dies sollte als die richtige Antwort außerhalb von Var-Debatten markiert werden. Dies ist der ausgewogene Ansatz
Brian Ogden
Können Sie ein Beispiel geben, wie "wo offensichtlich" entschieden wird?
rollt
13

Meine Regel lautet:

  • Deklarieren Sie eine primitive Art (dh byte, char, string, int[], double?, decimal, etc.)? -> Verwenden Sie den Typ:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • Deklarieren Sie einen komplexen Typ (dh List<T>, Dictionary<T, T>, MyObj)? -> Verwenden Sie var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
Sumner Evans
quelle
Ich möchte nicht zustimmen, string myStr = "foo";ist offensichtlich, dass es eine Zeichenfolge ist. Ich würde alle Ihre Beispiele in die Kategorie var verwenden ... und Deklarationen, die von einer Methode zur Verwendung des Explizitätstyps zurückgegeben werden. Aber am Ende des Tages ist es alles, was Sie und Ihr Team für das jeweilige Projekt für besser halten.
Dean Meehan
12

Ich möchte nur darauf hinweisen, dass die Verwendung von "var" in den C # -Codierungskonventionen empfohlen wird

wenn der Typ der Variablen auf der rechten Seite der Zuweisung ersichtlich ist oder wenn der genaue Typ nicht wichtig ist

Das ist wahrscheinlich der Grund, warum der Tipp in ReSharper standardmäßig aktiviert ist. Sie bieten auch einige Fälle, in denen die Lesbarkeit direkt im selben Dokument nicht verbessert wird.

jose
quelle
Das ist großartig, wenn Sie wissen, dass der Typ stammt System.Diagnostics.PerformanceCounter() - Sie können den Leistungsindikator leicht anhand der eingebauten Diagnoseklasse erkennen. Aber welcher Typ wird hier zurückgegeben? var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? Kein Hinweis auf die Taktung, insbesondere wenn Ihre Lösung weit über 100 Projekte enthält.
Piotr Kula
"Empfohlen, wenn der Typ der Variablen offensichtlich ist" und "Sie bieten auch einige Fälle, in denen die Lesbarkeit direkt im selben Dokument nicht verbessert wird". Ehrlich gesagt, ich glaube, ich habe Ihren Standpunkt verfehlt. Meine Antwort sagt dasselbe, was Sie sagen.
Jose
6

ReSharper empfiehlt, varda es dazu neigt, die Objekterstellung übersichtlich zu gestalten.

Vergleichen Sie diese beiden Beispiele:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

Es ist nur eine Kurzschrift, die leichter zu lesen sein soll.

Ich denke, es ist in Ordnung, wenn Sie neue Objekte explizit mit "new" erstellen. In Ihrem Beispiel ist es jedoch möglicherweise nicht offensichtlich, ob die Klassen nicht richtig benannt wurden.

Paul Sasik
quelle
6

Übrigens unterscheidet ReSharper zwischen "Sie möchten diesen Vorschlag möglicherweise auf Ihren Code anwenden" und "Ihr Code ist fehlerhaft, soll ich ihn beheben?". Das varSchlüsselwort befindet sich in der Kategorie "Vorschläge", zusammen mit Dingen wie "Invertieren, wenn die Verschachtelung reduziert werden soll". du musst ihm nicht folgen.

Sie können konfigurieren, wie ärgerlich die einzelnen Warnungen sind, indem Sie das Dialogfeld "Optionen" oder direkt das Popup-Menü für diese Warnung verwenden. Sie können Dinge wie den varVorschlag herabstufen , damit sie weniger auffällig sind, oder Sie können Dinge wie die Warnung "Erweiterungsmethode verwenden" aktualisieren, damit sie als tatsächlicher Fehler angezeigt wird.

Tim Robinson
quelle
5

Die varFunktion von .Net 3.0 ist nur die Typinferenz , die typsicher ist und häufig das Lesen Ihres Codes erleichtert. Sie müssen dies jedoch nicht und können diese Empfehlung in Resharper deaktivieren, wenn Sie möchten.

Klaus Byskov Pedersen
quelle
4

Var ist unglaublich! Ich bin auf viele Entwickler gestoßen, die den Eindruck haben, varan einen dynamischen Typ gebunden zu sein, das ist es nicht. Es ist immer noch statisch typisiert, es wird nur vom Compiler entschieden.

Hier sind einige erstaunliche Vorteile der Verwendung von var

Weniger typing var ist kürzer und leichter zu lesen, zum Beispiel

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Yuk.

var postcodes = new Dictionary<int,IList<string>>()\ o / \ o /

Beschreibendere Variablennamen - dünn, aber ich denke, es ist wichtig, die fließende Natur des varLeuchten hier zum Leuchten zu bringen. Wie vares ein bisschen vage ist, ermutigt es wirklich einen eher beschreibenden Variablennamen, anstatt den Typ für sich selbst sprechen zu lassen.

Weniger Codeänderungen - wenn sich der Rückgabetyp eines Methodenaufrufs ändert. Sie müssen nur den Methodenaufruf ändern, nicht jeden Ort, an dem er verwendet wird.

Anonyme Typen - anonyme Typen sind ein wirklich leistungsfähiges Konzept, vor allem in Bereichen wie WebAPI Teilressourcen . Ohne var können sie nicht verwendet werden.

Manchmal ist es jedoch nützlich, Typen explizit zu deklarieren, und ich finde dies am nützlichsten in Grundelementen oder Strukturen. Zum Beispiel finde ich diese Syntax persönlich nicht sehr nützlich:

for(var i = 0; i < 10; i++) 
{

}

vs.

for(int i = 0; i < 10; i++) 
{

}

Es hängt alles varvon Ihren persönlichen Vorlieben ab, aber die Verwendung wird Ihre Entwicklung wirklich beschleunigen und eine ganze Welt anonymer Typgüte freischalten.

KnowHoper
quelle
2

Es gibt keinen technischen Unterschied. Wenn Sie var verwenden, wird der Typ vom Compiler impliziert. Wenn Sie einen Code wie diesen haben:

var x = 1;

x ist ein int und es können keine anderen Werte zugewiesen werden.

Das Schlüsselwort var ist nützlich, wenn Sie den Typ der Variablen ändern. Sie müssen dann nur eine Änderung anstelle von zwei vornehmen:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
eWolf
quelle
1
@AlexKamburov der Code 10 Zeilen unten wird sowieso brechen, ist nicht mit var verwandt.
user3285954
1
@ user3285954 In einigen Fällen kann var das Problem verbergen, und dann können die Dinge hässlich werden. Das Problem liegt nicht beim Schreiben von Code, sondern in der Wartbarkeit. Einige behaupten, es sei sauberer mit var, aber ich sehe es manchmal als Verschleierung. Es ist nah an einer religiösen Debatte. brad-smith.info/blog/archives/336 Ich persönlich verwende var nur für Linq-Anweisungen und andere Stellen, an denen die Deklaration des Typs wirklich ausführlich ist. Ich denke, var ist eine gute Ergänzung und die Leute müssen Anders Hejlsbergs Kommentare zu den Gründen für die Einführung beachten.
Alex Kamburov
2

Das varSchlüsselwort wurde in C # 3.0 eingeführt. Dadurch können wir vergessen, unseren Typ explizit anzugeben.

Es gibt keinen wirklichen Unterschied, ob Sie verwenden

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

oder

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

außer reine Lesbarkeit und geringere Fehlerwahrscheinlichkeit.

Es scheint ein klischeehaftes Beispiel zu sein, aber sagen Sie, dass Folgendes Ihrem Verständnis helfen kann:

var myInt = 23;

gibt einen intTyp zurück, während

var myInt = "23";

gibt einen stringTyp zurück.

MSDN-Referenz

Daniel May
quelle
2

Die Angabe eines expliziten Objekttyps ist irgendwie redundant. Sogar ins Englische übersetzt klingt das überflüssig: "Ein Objekt vom Typ X in eine Variable vom Typ X einfügen" vs "Ein Objekt vom Typ X in eine Variable einfügen".

Die Verwendung von 'var' hat jedoch ihre Grenzen . Es verhindert die folgende Verwendung von Polymorphismus, der reine Schönheit ist :

Angenommen, ein Hund erweitert das Tier. Katze erweitert Tierklassenhierarchie:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Derselbe Code, bei dem x mit 'var' deklariert ist, wird nicht kompiliert .

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Zurück zur ursprünglichen Frage: Ich verwende Resharper nicht, aber ich gehe davon aus, dass dies klug genug ist, um zu erkennen, wann 'var' nicht verwendet werden soll. :-)

xtrem
quelle
4
Unnötiges Casting (mit as) ist schrecklich. Sie verwandeln Kompilierungsfehler in Laufzeitfehler, wenn Sie so etwas wie Animal x = new Cat(); DoStuffWithDog(x as Dog); Warum x wiederverwenden? Hund x = neuer Hund (), Katze y = neue Katze (), Boom keine mögliche Mehrdeutigkeit mehr.
Mark Sowul
Casting (mit 'as' oder nicht) kann zu einem Laufzeitfehler führen. Was ist so schrecklich am Casting, wenn du weißt, was du tust? Warum x wiederverwenden? Das Beispiel hier ist veranschaulichend. Das Ziel des Beispiels ist es zu zeigen, wie die Verwendung von 'var' zu Einschränkungen führen kann, wenn eine Referenz polymorph sein soll.
Xtrem
5
Nein, das kann es nicht: Polymorphismus ist das Gegenteil von dem, was hier vor sich geht. Dies versucht, Objekte vom Typ Animalan Methoden zu übergeben, die Dogund annehmen Cat. Polymorphismus ist das Gegenteil: so dass Sie Objekte vom Typ passieren kann Dogund Catin einem Verfahren , das dauert Animal, zum Beispiel void Walk(Animal a): Walk(new Cat()),Walk(new Dog())
Mark Sowul
Sie sollten Variablen auf diese Weise nicht wiederverwenden, da dies zu sehr bösen Fehlern führt. Bei kurzen Methoden nicht so offensichtlich, aber wenn Sie 15 bis 20 Codezeilen haben, werden Sie vergessen, was x ist. Sei nicht faul: var dog = new Dog (); DoStuff (Hund); var cat = new Cat (); DoStuff (Katze);
user3285954
2
Kein Kampf. Ich habe keine Gefühle für die Deklaration von Variablen (implizit oder explizit). Ich benutze tatsächlich mindestens einen der meisten Tage. Ich möchte nur hervorheben, dass der Compiler bei Auswahl der impliziten (var) Methode den engstmöglichen Typ für Sie festlegt. Welches kann nicht immer das sein, was Sie wollen. Das ist alles.
Xtrem
2

Meiner Ansicht nach varsollte nur verwendet werden, wenn sofort klar ist, um welchen Typ es sich bei der Definition des Werts der Variablen handelt.

Beispiel:

var s = "string value";

Es ist offensichtlich, dass sa string.

Ich halte es auch für angebracht, wenn der Variablentypname sehr komplex ist.

Beispiel:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

Abgesehen von diesen Szenarien sehe ich keinen Gewinn, der durch die Verwendung erzielt werden varkann, aber ich kann mir einige Szenarien vorstellen, in denen dies nachteilig sein kann:

Zum Beispiel ein Einweg-Typ, dessen rechter Variablenwert den Typ nicht klar anzeigt. Die Entsorgung des IDisposable kann leicht vergessen werden

Beispiel:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
James Wierzba
quelle
1

'var' fügt Ihrem Code eine Art "dynamisches" Element hinzu (obwohl der Code natürlich streng typisiert bleibt). Ich rate davon ab, es in Fällen zu verwenden, in denen der Typ nicht klar ist. Betrachten Sie dieses Beispiel:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

Sollte der Rückgabetyp von GetTheObjectFromDatabase () von Typ A nach B geändert werden, werden wir dies nicht bemerken, da beide Klassen DoSomething () implementieren. Der Code kann jetzt jedoch tatsächlich etwas völlig anderes tun.

Dies kann so subtil sein, als würden beide verschiedene Dinge in ein Protokoll schreiben, sodass Sie möglicherweise nicht bemerken, dass es zu spät ist.

Die folgende Verwendung von var sollte immer in Ordnung sein:

var abc = new Something();
lolaldanee
quelle
1

Für diejenigen, die die ständige Verwendung von "var" nicht mögen, können Sie ReSharper auch daran hindern, standardmäßig var zu verwenden, wenn Sie "Variable einführen" ausführen. Dies war etwas, das mich lange Zeit frustrierte, es war immer standardmäßig var und ich änderte es jedes Mal.

Diese Einstellungen finden Sie unter Codebearbeitung> C #> Codestil

Geben Sie hier die Bildbeschreibung ein

Derek
quelle
0

Es gibt keinen technischen Unterschied (wie eWolf hervorhob). Sie können den einen oder anderen verwenden, der generierte CLR-Code sieht gleich aus.

Meiner Meinung nach besteht der Hauptvorteil darin, dass Sie dazu gezwungen werden, bessere Variablennamen zu verwenden. In Ihrem Beispiel ist 'foo' eine ziemlich schlechte Wahl für einen Variablennamen.

Jaco Pretorius
quelle
0

Laut JetBrains (dem Autor von ReSharper) empfehlen sie standardmäßig die Verwendung von var.

Von ihrer Website :

Die Verwendung implizit typisierter lokaler Variablen (auch als varSchlüsselwort bezeichnet), die in C # 3.0 eingeführt wurden, ist sehr beliebt geworden, da sie in vielen Szenarien die Lesbarkeit verbessert. Standardmäßig empfiehlt ReSharper auch die Verwendung von varSchlüsselwörtern. Die Einstellungen für die Verwendung sind jedoch flexibel konfigurierbar. Sie können beispielsweise in bestimmten Fällen oder überall explizite Typen verwenden, und ReSharper hilft Ihnen bei der Durchsetzung Ihrer Einstellungen.

Jeff Reddy
quelle
Wo kann ich konfigurieren, wann eine explizite Typdeklaration erforderlich ist?
user764754