Frage

Nehmen Sie das folgende Snippet:

List<int> distances = new List<int>();

Wurde die Redundanz durch die Sprachdesigner gedacht? Wenn ja, warum?

War es hilfreich?

Lösung

Der Grund, der Code ist zu offensichtlich überflüssig ist, weil zu einem neuen Programmierer, scheint es die gleiche Sache zweimal zu definieren. Aber das ist nicht das, was der Code tut. Es wird definiert, zwei getrennte Dinge, die nur von der gleichen Art sein passieren. Es wird definiert, die folgende:

  1. Eine Variable mit dem Namen Entfernungen vom Typ List<int>.
  2. Ein Objekt auf dem Heap des Typs List<int>.

Beachten Sie Folgendes:

Person[] coworkers = new Employee[20];

Hier ist die Nicht-Redundanz ist klarer, da die Variablen und das zugeordnete Objekt sind von zwei verschiedenen Typen (eine Situation, die, wenn der Objekttyp von legal leitet oder implementiert den Variablentyp).

Andere Tipps

Was ist redudant über das?

List<int> listOfInts = new List<int>():

Deutsche Übersetzung: (EDIT, ein wenig zur Klärung bereinigt)

  • Erstellen Sie einen Zeiger vom Typ List und benennen Sie es listofInts.
  • listOfInts wird nun erstellt, aber es ist nur ein Verweis Zeiger auf nirgendwo (null)
  • Erstellen Sie jetzt ein Objekt vom Typ List auf dem Heap, und gibt den Zeiger auf listOfInts.
  • Jetzt listOfInts verweist auf eine List auf dem Heap.

Nicht wirklich ausführliche, wenn Sie darüber nachdenken, was es tut.

Natürlich gibt es eine Alternative:

var listOfInts = new List<int>();

Hier haben wir C # 's Typinferenz verwenden, weil Sie sofort es zuweisen, C # herausfinden können, welche Art Sie durch das Objekt erstellen möchten nur in dem Heap erstellt.

Um vollständig zu verstehen, wie die CLR-Typen behandelt, empfehle ich das Lesen CLR Via C # .

Sie können immer sagen:

 var distances = new List<int>();

Wie andere gesagt haben: var entfernt die Redundanz, aber es hat Potential negative Wartung Folgen. Ich würde sagen, dass es auch Potenzial hat, positive Wartung Folgen.

Zum Glück Eric Lippert schreibt über es viel mehr beredt als ich: http://csharpindepth.com/ViewNote.aspx?NoteID=63 http://csharpindepth.com/ViewNote.aspx?NoteID=61

Da eine Art erklärt nicht unbedingt etwas damit die Initialisierung zu tun hat.

Ich kann erklären

List<int> foo; 

und lassen Sie es später initialisiert werden. Wo ist dann die Redundanz? Vielleicht ist es den Wert von einer anderen Funktion wie Buildlist empfängt ().

Wie andere das neue Schlüsselwort var erwähnt haben können Sie rund um das zu bekommen, aber Sie wurde die Variable bei der Deklaration initialisiert werden, so dass der Compiler kann sagen, welche Art es ist.

anstatt zu denken, es als überflüssig, daran zu denken, dass als Merkmal konstruieren, damit Sie eine Linie speichern.

anstelle von

Liste Entfernungen; Entfernungen = new List ();

c # können Sie legen sie auf einer Linie.

Eine Zeile sagt: „Ich werde eine Variable aufgerufen werden Entfernungen , und es wird der Typ-Liste sein.“ Eine andere Linie sagt: „Vergeben Sie einen neuen Liste und rufen Sie den parameterlosen Konstruktor“.

Ist das zu überflüssig? Vielleicht. tun es auf diese Weise gibt Ihnen einige Dinge, obwohl

1 . Abscheidet die Variablendeklaration von Objektzuordnung. Zulassen:

IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();

2 Es ermöglicht eine starke statische Typprüfung durch den Compiler -.. Geben Compiler-Fehler, wenn Ihre Erklärungen der Zuordnungen nicht übereinstimmen, anstatt Laufzeitfehler

Sind diese beiden für das Schreiben von Software erforderlich? Nein. Es gibt viele Sprachen, die dies nicht tun, und / oder unterscheiden sich von vielen anderen Punkten.

"Doctor! Es tut weh, wenn ich dies tun!" - "Tu das nicht mehr"

Wenn Sie feststellen, dass Sie brauchen oder wollen die Dinge nicht, dass c # Sie gibt, versuchen, andere Sprachen. Selbst wenn Sie sie nicht benutzen, können andere, die wissen, geben Sie einen enormen Schub, wie Sie Probleme angehen. Wenn Sie eines tun verwenden, toll!

So oder so, kann man genug Perspektive findet sie zu erlauben, zu sagen: „Ich brauche nicht den strengen statischen Typen von dem C # -Compiler erzwungen zu überprüfen. Ich werde verwenden Python“, anstatt flammend c # als auch überflüssig.

Könnte auch tun:

var distances = new List<int>();

Die Compiler Verbesserungen für C # 3.0 beseitigen einige diese Art der Sache (die mit .NET 3.5 entspricht). So können Sie Ihren Code nun wie folgt geschrieben werden:

var distances = new List<int>();

Der aktualisierte Compiler ist viel besser Typen herauszufinden, basierend auf zusätzliche Informationen in der Erklärung. Das bedeutet, dass es weniger Fälle, in denen Sie benötigen einen Typ angeben entweder für eine Zuordnung, oder als Teil eines Allgemein.

Davon abgesehen, gibt es noch einige Bereiche, die verbessert werden könnten. Manches davon ist API und einige sind einfach aufgrund der Beschränkungen der starken Typisierung.

Die redunancy war nicht beabsichtigt, per se, sondern war ein Nebeneffekt der Tatsache, dass alle Variablen und Felder benötigt, um eine Typdeklaration haben. Wenn Sie berücksichtigen, dass alle Instanzen auch das Objekt vom Typ des Namen erwähnt in einem neue Ausdruck erhalten Sie redundante Aussagen.

Jetzt mit Typ-Inferenz des var Schlüsselwort verwendet wird, kann die Redundanz beseitigt werden. Der Compiler ist intelligent genug, um es herauszufinden. Die nächste C ++ hat auch ein Auto Schlüsselwort, das die gleiche Sache tut.

Der Hauptgrund, sie eingeführt var , obwohl, war für anonyme Typen, die keinen Namen haben:

var x = new {Foo = Bar, Number = 1};

Es ist nur „redundant“, wenn Sie es vergleichen, um dynamisch typisierten Sprachen. Es ist nützlich für Polymorphismus und Finden Fehler bei der Kompilierung. Außerdem macht es Code auto-complete / intellisense einfacher für Ihre IDE (wenn Sie ein).

Eine historische Artefakt der statischen Typisierung / C-Syntax; Vergleichen Sie die Ruby-Beispiel:

distances = []

C # auf jeden Fall wird immer weniger ausführlich nach der Zugabe von funktionaler Unterstützung.

Verwenden var wenn es offensichtlich ist, was der Typ für den Leser ist.

//Use var here
var names = new List<string>();

//but not here
List<string> names = GetNames();

Von microsofts C # programing Führung

  

Das Schlüsselwort var kann auch nützlich sein   wenn der spezifische Typ der Variablen   ist mühsam auf der Tastatur eingeben oder   liegt auf der Hand, oder die nicht hinzufügen   Lesbarkeit des Codes

Ihr besonderes Beispiel ist in der Tat ein bisschen ausführliche, aber in den meisten Möglichkeiten, C # ist eher mager.

Ich würde viel lieber diesen (C #)

int i;

, um diese (VB.NET)

Dim i as Integer

Nun, das bestimmte Beispiel, das Sie gewählt hat, ist etwas über .NET im Allgemeinen, die ein bisschen an der langen Seite ist, aber ich glaube nicht, dass C # 's Schuld. Vielleicht sollte die Frage umformuliert werden: „Warum .NET-Code ist so ausführliche?“

Ich sehe ein anderes Problem mit der Verwendung von var für Faulheit wie die

var names = new List<string>();

Wenn Sie var verwenden, die Variable mit dem Namen „Name“ als List<string>, getippt, aber Sie würden nur schließlich eine der von List<T>. geerbten Schnittstellen verwenden

IList<string> = new List<string>();
ICollection<string> = new List<string>();
IEnumerable<string> = new List<string>();

Sie können automatisch alles davon verwenden, aber können Sie prüfen, welche Schnittstelle Sie an der Zeit, die Sie schrieb den Code?

verwenden wollte

Das Schlüsselwort var nicht verbessert die Lesbarkeit in diesem Beispiel.

In vielen der Antworten auf diese Frage, denken die Autoren wie Compiler oder Apologeten. Eine wichtige Regel von guter Programmierung ist Sie sich nicht wiederholen!

Diese unnötige Wiederholung zu vermeiden, ist ein explizites Designziel von Go, zum Beispiel:

  

Stottern (foo.Foo* myFoo = new(foo.Foo)) reduziert wird durch einfache Art Ableitung mit dem := Konstrukt declare-and-initialisieren.

Weil wir süchtig nach Compiler und Compiler-Fehler.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top