405 Stimmen

Verwendung des Schlüsselworts var in C#

Nach einer Diskussion mit Kollegen über die Verwendung des Schlüsselworts "var" in C# 3 habe ich mich gefragt, welche Meinung die Leute zur angemessenen Verwendung der Typinferenz über var haben?

Zum Beispiel habe ich var in fragwürdigen Situationen ziemlich faul verwendet, z.B.:-

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

Weitere legitime Verwendungszwecke von var sind folgende:-

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

Interessanterweise scheint LINQ eine Art Grauzone zu sein, z.B.:-

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

Es ist klar, was daraus resultiert, dass es sich um einen Typ handelt, der IEnumerable implementiert, aber es ist nicht ganz so offensichtlich wie bei einer var, die ein neues Objekt deklariert.

Noch schlimmer ist es, wenn es um LINQ to objects geht, z.B.:-

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

Dies ist nicht besser als das Äquivilent foreach(var item in someList) { // ... } gleichwertig.

Es gibt hier ein echtes Problem mit der Typsicherheit - wenn wir zum Beispiel die Ergebnisse dieser Abfrage in eine überladene Methode stellen würden, die IEnumerable<int> und IEnumerable<double> akzeptiert, könnte der Aufrufer versehentlich den falschen Typ übergeben.

var fait eine starke Typisierung beibehalten, aber die Frage ist, ob es gefährlich ist, wenn der Typ bei der Definition nicht sofort ersichtlich ist, was noch verstärkt wird, wenn Überladungen bedeuten, dass Compilerfehler nicht ausgegeben werden, wenn Sie einer Methode versehentlich den falschen Typ übergeben.

2voto

Christopher Barber Punkte 2340

Abgesehen von den Bedenken hinsichtlich der Lesbarkeit gibt es ein echtes Problem mit der Verwendung von "var". Bei der Definition von Variablen, die später im Code zugewiesen werden, kann dies zu fehlerhaftem Code führen, wenn sich der Typ des Ausdrucks, der zur Initialisierung der Variablen verwendet wird, zu einem engeren Typ ändert. Normalerweise wäre es sicher, eine Methode so zu refaktorisieren, dass sie einen engeren Typ zurückgibt als zuvor: z.B. den Rückgabetyp 'Object' durch die Klasse 'Foo' zu ersetzen. Wenn es aber eine Variable gibt, deren Typ von der Methode abgeleitet wird, dann bedeutet die Änderung des Rückgabetyps, dass dieser Variable nicht länger ein Nicht-Foo-Objekt zugewiesen werden kann:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

In diesem Beispiel würde also eine Änderung des Rückgabetyps von getFoo die Zuweisung von getNonFoo illegal machen.

Das ist keine große Sache, wenn getFoo und alle seine Verwendungen im gleichen Projekt sind, aber wenn getFoo in einer Bibliothek für die Verwendung durch externe Projekte ist, können Sie nicht mehr sicher sein, dass die Verengung des Rückgabetyps nicht den Code einiger Benutzer kaputt macht, wenn sie 'var' so verwenden.

Genau aus diesem Grund haben wir, als wir eine ähnliche Funktion zur Typinferenz in die Programmiersprache Curl aufgenommen haben (in Curl 'def' genannt), Zuweisungen an Variablen verhindert, die mit dieser Syntax definiert wurden.

2voto

nedruod Punkte 1094

Bei der statischen Typisierung geht es um Verträge, nicht um Quellcode. Die Idee ist, dass die statischen Informationen in einer einzigen Zeile einer "kleinen" Methode stehen müssen. In den allgemeinen Leitlinien wird empfohlen, selten mehr als 25 Zeilen pro Methode zu verwenden.

Wenn eine Methode so groß ist, dass man nicht eine einzige Variable innerhalb dieser Methode im Auge behalten kann, macht man etwas anderes falsch, was jede Kritik an var verblassen lässt.

Eines der Hauptargumente für var ist, dass es das Refactoring vereinfachen kann, weil man sich keine Sorgen mehr machen muss, dass man seine Deklaration zu restriktiv gestaltet hat (d.h. man hat List<> verwendet, obwohl man IList<> oder IEnumerable<> hätte verwenden sollen). Sie müssen zwar immer noch über die Signatur der neuen Methoden nachdenken, aber zumindest müssen Sie nicht mehr zurückgehen und Ihre Deklarationen ändern, um sie anzupassen.

2voto

Will Marcouiller Punkte 23205

var ist ein Platzhalter, der für die anonymous types in C# 3.0 und LINQ.

Sie ermöglicht das Schreiben von LINQ-Abfragen für eine geringere Anzahl von Spalten innerhalb einer Sammlung. Es ist nicht notwendig, die Informationen im Speicher zu duplizieren, sondern nur das zu laden, was notwendig ist, um das zu tun, was Sie tun müssen.

Die Verwendung von var ist gar nicht schlecht, denn es ist eigentlich kein Typ, sondern, wie an anderer Stelle erwähnt, ein Platzhalter für den Typ, der auf der rechten Seite der Gleichung definiert wird und werden muss. Dann wird der Compiler das Schlüsselwort durch den Typ selbst ersetzen.

Es ist besonders nützlich, wenn der Name eines Typs trotz IntelliSense sehr lang ist. Schreiben Sie einfach var und instanziieren Sie es. Die anderen Programmierer, die Ihren Code später lesen, werden leicht verstehen, was Sie tun.

Das ist so, als würde man

public object SomeObject { get; set; }

anstelle von:

public object SomeObject {
    get {
        return _someObject;
    } 
    set {
        _someObject = value;
    }
}
private object _someObject;

Jeder weiß, was die Immobilie macht, denn jeder weiß, was die var Schlüsselwort tut, und beide Beispiele neigen dazu, die Lesbarkeit zu erleichtern, indem sie den Code leichter machen, und machen es angenehmer für den Programmierer, effektiven Code zu schreiben.

2voto

Pat Punkte 5260

Nachdem ich gerade auf die Frameworks 3.0 und 3.5 umgestellt hatte, erfuhr ich von diesem Schlüsselwort und beschloss, es auszuprobieren. Bevor ich irgendeinen Code einfügte, wurde mir klar, dass es rückwärtsgewandt war, da es auf eine ASP-Syntax zurückging. Also beschloss ich, die höheren Ebenen zu befragen, um zu sehen, was sie dachten.

Sie sagten, ich solle es tun, also benutze ich es.

Deshalb vermeide ich es, sie zu verwenden, wenn der Typ eine Untersuchung erfordert, wie in diesem Fall:

var a = Firma.GetRecords();

Jetzt könnte es nur eine persönliche Sache sein, aber ich kann nicht sofort schauen, dass und bestimmen, wenn seine eine Sammlung von Record-Objekte oder ein String-Array, die den Namen der Datensätze. Wie auch immer, ich glaube, dass eine explizite Deklaration in einem solchen Fall nützlich ist.

1voto

andypaxo Punkte 5691

Meiner Meinung nach gibt es kein Problem bei der Verwendung von var schwer. Es handelt sich nicht um einen eigenen Typ (Sie verwenden immer noch statische Typisierung). Stattdessen ist es nur eine Zeitersparnis, so dass der Compiler herausfinden kann, was zu tun ist.

Wie jede andere Zeitersparnis (wie z. B. automatische Eigenschaften), ist es ist eine gute Idee, zu verstehen, was es ist und wie es funktioniert, bevor man es überall einsetzt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X