Früher habe ich eine Frage gestellt, warum ich sehe, dass so viele Beispiele das var
Schlüsselwort verwenden, und die Antwort erhalten, dass es zwar nur für anonyme Typen erforderlich ist, aber dennoch verwendet wird, um das Schreiben von Code "schneller" / einfacher und "nur weil" zu machen.
Im Anschluss an diesen Link ( „C # 3.0 - Var Is not Objec“) Ich sah , dass var
auf den richtigen Typ nach unten in der IL kompiliert wird (Sie werden es etwa auf halbem Weg nach unten Artikels).
Meine Frage ist, wie viel mehr, wenn überhaupt, IL-Code mit dem var
Schlüsselwort benötigt, und wäre es sogar annähernd messbar, wenn die Leistung des Codes überall verwendet würde?
c#
performance
variables
var
Jeff Keslinke
quelle
quelle
var
funktionieren definitiv mit "Alle Referenzen suchen " in Visual Studio 2019. Wenn es also jemals kaputt gegangen ist, wurde es behoben. Ich kann jedoch bestätigen, dass es bereits in Visual Studio 2012 funktioniert. Daher bin ich mir nicht sicher, warum Sie behauptet haben, dass es nicht funktioniert hat.var
wird nicht als Referenz angesehen,X
wenn Sie "Alle Referenzen suchen " verwendenX
. Interessanterweise , wenn Sie „Alle Verweise finden“ verwenden , um aufvar
in dieser Aussage, es wird Ihnen Verweis zeigenX
(auch wenn es immer noch nicht die Listevar
Anweisung). Wenn der Cursor eingeschaltet istvar
, werden außerdem alle InstanzenX
im selben Dokument hervorgehoben (und umgekehrt).Antworten:
Es gibt keinen zusätzlichen IL-Code für das
var
Schlüsselwort: Die resultierende IL sollte für nicht anonyme Typen identisch sein. Wenn der Compiler diese IL nicht erstellen kann, weil er nicht herausfinden kann, welchen Typ Sie verwenden möchten, wird ein Compilerfehler angezeigt.Der einzige Trick besteht darin
var
, einen genauen Typ abzuleiten, bei dem Sie möglicherweise eine Schnittstelle oder einen übergeordneten Typ ausgewählt haben, wenn Sie den Typ manuell festlegen.Update 8 Jahre später
Ich muss dies aktualisieren, da sich mein Verständnis geändert hat. Ich glaube jetzt, dass es möglich sein kann
var
, die Leistung in der Situation zu beeinflussen, in der eine Methode eine Schnittstelle zurückgibt, aber Sie hätten einen genauen Typ verwendet. Wenn Sie beispielsweise diese Methode haben:Betrachten Sie diese drei Codezeilen, um die Methode aufzurufen:
Alle drei werden wie erwartet kompiliert und ausgeführt. Die ersten beiden Zeilen sind jedoch nicht genau gleich, und die dritte Zeile entspricht eher der zweiten als der ersten. Da die Signatur von
Foo()
eine zurückgebenIList<int>
soll, erstellt der Compiler diebar3
Variable auf diese Weise.Vom Standpunkt der Leistung aus werden Sie es meistens nicht bemerken. Es gibt jedoch Situationen, in denen die Leistung der dritten Zeile möglicherweise nicht ganz so schnell ist wie die Leistung der ersten . Wenn Sie die
bar3
Variable weiterhin verwenden , kann der Compiler möglicherweise Methodenaufrufe nicht auf die gleiche Weise versenden.Beachten Sie, dass es möglich ist (wahrscheinlich sogar), dass der Jitter diesen Unterschied beseitigen kann, dies ist jedoch nicht garantiert. Im Allgemeinen sollten Sie immer noch davon ausgehen
var
, dass dies kein Leistungsfaktor ist. Es ist sicherlich überhaupt nicht so, als würde man einedynamic
Variable verwenden. Aber zu sagen, dass es überhaupt keinen Unterschied macht, kann es übertreiben.quelle
var i = 42;
(Folgertyp ist int) ist NICHT identisch mitlong i = 42;
. In einigen Fällen machen Sie möglicherweise falsche Annahmen über die Typinferenz. Dies kann zu schwer fassbaren Laufzeitfehlern führen, wenn der Wert nicht passt. Aus diesem Grund ist es möglicherweise immer noch eine gute Idee, explizit zu sein, wenn der Wert keinen expliziten Typ hat. So wäre zum Beispielvar x = new List<List<Dictionary<int, string>()>()>()
akzeptabel, ist abervar x = 42
etwas mehrdeutig und sollte als geschrieben werdenint x = 42
. Aber für jeden sein eigenes ...var x = 42;
ist nicht mehrdeutig. Ganzzahlige Literale sind vom Typint
. Wenn Sie eine wörtliche lange wollen, schreiben Sievar x = 42L;
.Foo
aList
anstelle von a zurückgegeben wirdIList
, werden alle drei Zeilen kompiliert, aber die dritte Zeile verhält sich wie die erste Zeile , nicht wie die zweite.Wie Joel sagt, ermittelt der Compiler zur Kompilierungszeit, welcher Typ var sein soll. Tatsächlich ist dies nur ein Trick, den der Compiler ausführt, um beispielsweise Tastenanschläge zu speichern
wird ersetzt durch
vom Compiler, bevor eine IL generiert wird. Die generierte IL ist genau so, als hätten Sie eine Zeichenfolge eingegeben.
quelle
Da hat noch niemand Reflektor erwähnt ...
Wenn Sie den folgenden C # -Code kompilieren:
Dann verwenden Sie Reflektor, Sie erhalten:
Die Antwort ist also eindeutig kein Laufzeit-Performance-Hit!
quelle
Für die folgende Methode:
Die IL-Ausgabe lautet wie folgt:
quelle
Der C # -Compiler leitet zur Kompilierungszeit den wahren Typ der
var
Variablen ab. Es gibt keinen Unterschied in der generierten IL.quelle
Um klar zu sein, es ist ein fauler Codierungsstil. Ich bevorzuge einheimische Typen, wenn ich die Wahl habe; Ich werde dieses zusätzliche bisschen "Rauschen" nehmen, um sicherzustellen, dass ich genau das schreibe und lese, was ich denke, dass ich zur Code- / Debug-Zeit bin. * Achselzucken *
quelle
var
die Leistung überhaupt beeinträchtigt wird. Sie geben nur Ihre Meinung dazu ab, ob die Leute es benutzen sollen.int
da diese nicht automatisch konvertiert werden kann. Diesfloat
ist jedoch genau das Gleiche, das passieren würde, wenn Sie sie explizit verwendenint
und dann ändern würdenfloat
. In jedem Fall beantwortet Ihre Antwort die Frage "var
Beeinträchtigt die Verwendung die Leistung?" Immer noch nicht. (insbesondere in Bezug auf generierte IL)Ich glaube, Sie haben nicht richtig verstanden, was Sie gelesen haben. Wenn es auf den richtigen Typ kompiliert wird, gibt es keinen Unterschied. Wenn ich das mache:
Der Compiler weiß, dass es sich um ein Int handelt, und generiert Code, als hätte ich geschrieben
Wie der Beitrag, auf den Sie verlinkt haben, besagt, wird er auf denselben Typ kompiliert . Es ist keine Laufzeitprüfung oder irgendetwas anderes, das zusätzlichen Code erfordert. Der Compiler findet nur heraus, welcher Typ sein muss, und verwendet diesen.
quelle
Die Verwendung von var verursacht keine Laufzeitleistungskosten. Ich würde jedoch vermuten, dass es Kosten für die Kompilierungsleistung gibt, da der Compiler auf den Typ schließen muss, obwohl dies höchstwahrscheinlich vernachlässigbar sein wird.
quelle
Wenn der Compiler eine automatische Typinferenz durchführen kann, gibt es keine Probleme mit der Leistung. Beide generieren denselben Code
Wenn Sie den Typ jedoch dynamisch konstruieren (LINQ ...),
var
ist dies Ihre einzige Frage, und es gibt einen anderen Mechanismus zum Vergleichen, um zu sagen, was die Strafe ist.quelle
Ich verwende immer das Wort var in Webartikeln oder Leitfäden.
Die Breite des Texteditors des Online-Artikels ist gering.
Wenn ich das schreibe:
Sie werden sehen, dass der oben gerenderte Vorcode-Text zu lang ist und sofort ausgeblendet wird. Der Leser muss nach rechts scrollen, um die vollständige Syntax anzuzeigen.
Deshalb verwende ich in Webartikel-Schriften immer das Schlüsselwort var.
Der gesamte gerenderte Vorcode passt einfach in den Bildschirm.
In der Praxis verwende ich zum Deklarieren von Objekten selten var. Ich verlasse mich auf Intellisense, um Objekte schneller zu deklarieren.
Beispiel:
Für die Rückgabe von Objekten aus einer Methode verwende ich var, um Code schneller zu schreiben.
Beispiel:
quelle
"var" ist eines der Dinge, die Menschen entweder lieben oder hassen (wie Regionen). Im Gegensatz zu Regionen ist var beim Erstellen anonymer Klassen unbedingt erforderlich.
Für mich ist var sinnvoll, wenn Sie ein Objekt direkt wie folgt neu erstellen:
Davon abgesehen können Sie ganz einfach Folgendes tun:
Dictionary<string, string> dict =
Neu und Intellisense wird den Rest für Sie hier ausfüllen.Wenn Sie nur mit einer bestimmten Schnittstelle arbeiten möchten, können Sie var nur verwenden, wenn die von Ihnen aufgerufene Methode die Schnittstelle direkt zurückgibt.
Resharper scheint auf der Seite der Verwendung von "var" zu stehen, was dazu führen kann, dass mehr Leute dies tun. Aber ich stimme zu, dass es schwieriger zu lesen ist, wenn Sie eine Methode aufrufen, und es nicht offensichtlich ist, was mit dem Namen zurückgegeben wird.
var selbst verlangsamt die Dinge nicht, aber es gibt eine Einschränkung, an die nicht viele Leute denken. Wenn Sie dies tun
var result = SomeMethod();
, erwartet der Code danach eine Art Ergebnis, bei dem Sie verschiedene Methoden oder Eigenschaften oder was auch immer aufrufen würden. WennSomeMethod()
die Definition in einen anderen Typ geändert wurde, aber der vom anderen Code erwartete Vertrag weiterhin erfüllt wurde, haben Sie gerade einen wirklich bösen Fehler erstellt (wenn natürlich keine Unit- / Integrationstests durchgeführt wurden).quelle
Es hängt von der Situation ab, wenn Sie versuchen, diesen Code unten zu verwenden.
Der Ausdruck wird in "OBJECT" konvertiert und verringert die Leistung so sehr, aber es ist ein isoliertes Problem.
CODE:
Oben Ergebnisse mit ILSPY.
Wenn Sie diesen Code ausführen möchten, verwenden Sie den folgenden Code und ermitteln Sie die Zeitdifferenz.
Grüße
quelle