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.

7voto

Keith Punkte 141163

In Ihrem Vergleich zwischen IEnumerable<int> y IEnumerable<double> müssen Sie sich keine Sorgen machen - wenn Sie den falschen Typ übergeben, lässt sich Ihr Code ohnehin nicht kompilieren.

Es gibt keine Bedenken hinsichtlich der Typsicherheit, da var es no dynamisch. Das ist nur Compiler-Magie, und alle unsicheren Aufrufe, die Sie machen, werden abgefangen.

Var ist für Linq unbedingt erforderlich:

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
    };

Jetzt schauen Sie sich anonAufzählung in intellisense und es wird etwa so aussehen IEnumerable<'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 schlau - getrennt generierte Typen haben denselben generierten Typ, wenn ihre Eigenschaften übereinstimmen.

Abgesehen davon ist es sinnvoll, solange Sie Intellisense haben, Folgendes zu verwenden var überall ist der Zusammenhang klar.

//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;

7voto

mqp Punkte 66863

Ich denke, das hängt von Ihrer Perspektive ab. Ich persönlich hatte noch nie Schwierigkeiten, ein Stück Code zu verstehen, weil var "Missbrauch", und meine Kollegen und ich verwenden es überall ziemlich häufig. (Ich stimme zu, dass Intellisense in dieser Hinsicht eine große Hilfe ist.) Ich begrüße es als eine Möglichkeit, sich wiederholenden Ballast zu entfernen.

Denn 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

wirklich so unmöglich wäre, würde niemand dynamisch typisierte Sprachen verwenden.

7voto

Christian Specht Punkte 34680

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

In diesem Fall würde ich z. B. var verwenden, weil Sie sofort sehen können, dass x vom Typ "MyClass" sein wird:

var x = new MyClass();

Ich würde in Fällen wie diesem NICHT var verwenden, da man die Maus über den Code ziehen und den Tooltip betrachten muss, um zu sehen, welchen Typ MyFunction zurückgibt:

var x = MyClass.MyFunction();

Besonders, ich niemals verwenden Sie var in Fällen, in denen die rechte Seite nicht einmal eine Methode, sondern nur ein Wert ist:

var x = 5;

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

6voto

BFree Punkte 100035

Während des Testens habe ich oft Code wie diesen gefunden:

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

Nun möchte ich manchmal sehen, was das SomeOtherThing selbst enthält, SomeOtherThing ist nicht der gleiche Typ, den CallMethod() zurückgibt. Da ich aber var verwende, ändere ich das einfach:

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

dazu:

var something = myObject.SomeProperty.SomeOtherThing;

Ohne var müsste ich den angegebenen Typ auf der linken Seite ebenfalls ständig ändern. Ich weiß, es ist unbedeutend, aber es ist extrem praktisch.

6voto

Neil Hewitt Punkte 2508

Verwenden Sie sie für anonyme Typen - dafür ist sie da. Alles andere geht zu weit. Wie viele Leute, die mit C aufgewachsen sind, bin ich es gewohnt, links von der Deklaration nach dem Typ zu suchen. Ich schaue nicht auf die rechte Seite, wenn ich nicht muss. Verwendung von var für irgendeine alte Erklärung macht mich das die ganze Zeit, was ich persönlich unangenehm finde.

Diejenigen, die sagen: "Es ist egal, verwenden Sie das, womit Sie zufrieden sind", sehen nicht das ganze Bild. Jeder wird irgendwann den Code anderer Leute übernehmen und sich mit den Entscheidungen auseinandersetzen müssen, die diese zu dem Zeitpunkt getroffen haben, als sie ihn geschrieben haben. Es ist schon schlimm genug, sich mit radikal unterschiedlichen Namenskonventionen oder - der klassische Kritikpunkt - mit Klammern auseinandersetzen zu müssen, ohne dass man auch noch das ganze ' var oder nicht" in den Mix einbringen. Der schlimmste Fall wäre, wenn ein Programmierer nicht die var und dann kommt ein Betreuer daher, der es liebt und den Code damit erweitert. Jetzt haben Sie also ein unheiliges Durcheinander.

Standards sind eine gute Sache, gerade weil sie bedeuten, dass man viel eher in der Lage ist, zufälligen Code in die Hand zu nehmen und ihn schnell zu verstehen. Je mehr Dinge unterschiedlich sind, desto schwieriger wird das. Und die Umstellung auf den "var everywhere"-Stil macht eine groß Unterschied.

Ich habe nichts gegen dynamische Typisierung, und ich habe nichts gegen implizite Typisierung - in Sprachen, die dafür ausgelegt sind. Ich mag Python sehr. Aber C# wurde als statische, explizit typisierte Sprache entwickelt und so sollte es auch bleiben. Die Regeln für anonyme Typen zu brechen war schon schlimm genug; dass die Leute das noch weiter treiben und die Idiome der Sprache noch mehr brechen, ist etwas, mit dem ich nicht glücklich bin. Jetzt, wo der Geist aus der Flasche ist, wird er nie mehr zurückkehren. C# wird sich in verschiedene Lager aufspalten. Das ist nicht gut.

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