2010-05-04 12 views

Antwort

7

Der C# -Compiler unterstützt Typ-Inferenz für Generika und auch häufig gesehen, wenn Sie das Schlüsselwort var verwenden.

Hier int wird aus dem Kontext zu entnehmen (a und b) und so ist <int> nicht benötigt. Es hält den Code sauberer und einfacher zu lesen, manchmal.

Manchmal ist Ihr Code möglicherweise klarer zu lesen, wenn Sie den Compiler auf den Typ schließen lassen. Manchmal ist es klarer, wenn Sie den Typ explizit angeben. Es ist ein Urteilsspruch über Ihre gegebene Situation.

+0

Er ist das 'var' Schlüsselwort nicht verwenden. – SLaks

+2

@SLaks: Ja, ich weiß. –

+0

@SLaks: "'auch' häufig gesehen" – Dykam

5

Der Compiler leitet den generischen Typparameter aus den Typen der tatsächlichen Parameter ab, die Sie übergeben haben.

Diese Funktion macht LINQ-Aufrufe viel einfacher. (Sie brauchen nicht numbers.Select<int, string>(i => i.ToString()) zu schreiben, weil der Compiler die int von numbers folgert und die string von ToString)

17

Es funktioniert, weil a und b ganze Zahlen sind, so dass der Compiler die generische Typargument für What ableiten kann.

In C# 3 kann der Compiler das Typargument auch dann ableiten, wenn die Typen nicht übereinstimmen, solange eine Erweiterung sinnvoll ist. Wenn beispielsweise c eine long wäre, würde What(a, c) als What<long> interpretiert werden.

Beachten Sie, dass, wenn, sagen wir, c ein string wäre, würde es nicht funktionieren.

+0

Beachten Sie auch, dass wenn Sie zwei verschiedene Typen haben, die sowohl 'Parent' erweitern als auch versuchen,' What (a, b) '(wobei a und b von diesen zwei verschiedenen Typen sind), nicht zu folgern Geben Sie als 'Eltern' ein. –

+1

@BlueRaja: das ist eigentlich der gleiche Fall, da in Dans Beispiel int und string beide Erweiterungen von Object sind. Das Design-Prinzip hier ist, dass C#, wenn er aufgefordert wird, ein "bestes" Mitglied einer Menge zu finden, immer ein Mitglied aus der Menge auswählt. Es wählt nie ein Mitglied von außerhalb des Sets. Auf die Frage, was das beste Mitglied von {Tiger, Giraffe} ist, heißt es nicht "Animal", es heißt, dass es kein bestes Mitglied gibt. –

1

Der Compiler ist intelligent genug, um herauszufinden, dass der generische Typ ‚int‘

7

Es ist für generische Methoden Typinferenz verwenden. Beachten Sie, dass diese zwischen C# 2 und 3. Zum Beispiel verändert haben, wäre dies nicht in C# gearbeitet hat 2:

What("hello", new object()); 

... während es würde in C# 3 (oder 4). In C# 2 wurde die Typrückschluss auf einer Argument-Basis durchgeführt, und die Ergebnisse mussten genau übereinstimmen. In C# 3 trägt jedes Argument Informationen bei, die dann zusammengesetzt werden, um die Typargumente abzuleiten. C# 3 unterstützt auch multi-phase Typ-Inferenz, wo der Compiler ein Typ-Argument ausarbeiten kann, dann sehen, ob es weitere Informationen über den Rest hat (z. B. aufgrund von Lambda-Ausdrücken mit impliziten Parametertypen). Im Grunde geht es weiter, bis es keine weiteren Informationen mehr erhalten kann, oder es endet - oder es sieht widersprüchliche Informationen. Die Typrückgabe in C# ist nicht so leistungsfähig wie der Hindley-Milner-Algorithmus, aber sie funktioniert auf andere Weise besser (insbesondere macht sie immer einen Vorwärtsfortschritt).

Weitere Informationen finden Sie in Abschnitt 7.4.2 der C# 3-Spezifikation.

2

Der Compiler kann den Typ T als int ableiten, da beide in What() übergebenen Parameter vom Typ int sind. Sie werden feststellen, dass viele der Linq-Erweiterungen mit Generics (als IEnumerable) definiert sind, aber in der Regel in der Art und Weise verwendet werden, die Sie anzeigen.