Vom C# specification, 7.5.3.2 Besseren Funktion Mitglied:
ein Argument Liste A mit einem Satz Argumente Ausdrücke {E1, E2, ..., EN} und zwei anwendbarer Funktionselemente Gegeben MP und MQ mit Parametertypen {P1, P2, ..., PN} und {Q1, Q2, ..., QN} wird MP definiert ein besseres Funktionselement als MQ, wenn
- für jeden Argument ist die implizite Konvertierung von EX nach QX nicht besser als die implizite Konvertierung von EX nach PX und
- Für mindestens ein Argument ist die Konvertierung von EX nach PX besser als die Konvertierung von EX nach QX.
Beachten Sie, dass die Angabe der Begriff implizite Konvertierung in einer Weise verwendet, die Identität Conversions enthält. Siehe 6.1 Implizite Konvertierungen:
Die folgenden Umwandlungen sind als implizite Konvertierungen klassifiziert:
- Identität Konvertierungen
- Implizite numerische Konvertierungen
- [...]
Und von 6.1.1 Identität Umwandlung:
Eine Identitäts Konvertierung wandelt von jeder Art auf die gleiche Art. [...]
Setliste Argumenttypen ist:
{ int, int }
Im ersten Fall werden die Kandidaten sind:
{ float, long }
{ int, float }
Lassen MP sein der erste Kandidat und MQ sind der zweite Kandidat.
- Es ist ein Argument X (= 1), wobei die implizite Konvertierung von EX QX ist besser als die implizite Konvertierung von EX zu PX:
int
bis int
ist besser als int
zu float
(weil es die gleiche Art).
Sei MP der zweite Kandidat und MQ der erste Kandidat.
- Es ist ein Argument X (= 2), wobei die implizite Konvertierung von EX qx besser als die implizite Konvertierung von EX zu PX:
int
bis long
ist besser als int
zu float
.
Kein Kandidat erfüllt die erste Kugel. Die bindungsbrechenden Mechanismen, die in der Spezifikation beschrieben sind, sind hier nicht anwendbar (da keine der Methoden generisch ist, weder variadisch, noch optionale Parameter usw.). Daher ist dieser Aufruf mehrdeutig.
Im zweiten Fall werden die Kandidaten sind:
{ long, float }
{ int, float }
Let MP der zweite Kandidat der erste Kandidat und MQ sein werden.
- Es ist ein Argument X (= 1), wobei die implizite Konvertierung von EX QX ist besser als die implizite Konvertierung von EX zu PX:
int
bis int
ist besser als int
zu long
(weil es die gleiche Art).
Sei MP der zweite Kandidat und MQ der erste Kandidat.
Es gibt kein Argument X, bei dem die implizite Konvertierung von EX nach QX besser ist als die implizite Konvertierung von EX nach PX.
Es ist ein Argument X (= 1), wobei die implizite Konvertierung von EX Px ist besser als die Umwandlung von EX zu QX: int
zu int
ist besser als int
zu long
.
Da der zweite Kandidat beide Kugeln erfüllt, ist es eine bessere Übereinstimmung als die erste.
Im dritten Fall sind die Kandidaten:
{ long, long }
{ int, float }
Genau wie im ersten Fall:
int
zu int
besser als int
zu long
ist.
- Aber
int
zu long
ist besser als int
zu float
.
So ist der Anruf wieder zweideutig.
Die Java Language Specification Zustände in 15.12.2.5 Die Wahl der spezifischste Methode:
Ein anwendbares Verfahren m1 spezifischer als andere anwendbare Methode m2 ist, für einen Aufruf mit dem Argument Ausdrücke e1. .., ek, wenn eine der folgenden Aussagen zutrifft:
m2 ist generisch, und m1 ist spezifischer als m2 für Argumentausdrücke e1, ..., ek § 18.5.4.
m2 ist nicht generisch, und m1 und m2 sind durch strikten oder lockeren Aufruf anwendbar, und wobei m1 formale Parametertypen S1, ..., Sn und m2 hat formale Parametertypen T1, ..., Tn, der Typ Si ist spezifischer als Ti für das Argument ei für alle i (1 ≤ i ≤ n, n = k).
m2 ist nicht generisch, und m1 und m2 sind durch variablen Arityaufruf anwendbar, und wo die ersten k variablen Arityparametertypen von m1 S1, ..., Sk sind und die ersten k variablen Arityparametertypen von m2 T1 sind , ..., Tk, der Typ Si ist spezifischer als Ti für das Argument ei für alle i (1 ≤ i ≤ k). Wenn m2 k + 1 Parameter aufweist, ist der k + 1-te variable Arityparametertyp von m1 ein Subtyp des k + 1-ten variablen Aristyparametertyps von m2.
Die obigen Bedingungen sind die einzigen Umstände, unter denen eine Methode spezifischer als eine andere sein kann.
Ein Typ S ist spezifischer als ein Typ T für einen beliebigen Ausdruck, wenn S <: T (§4.10).
wie vor zu beachten, dass die Beziehung beschrieben hier den Fall enthält, wobei S und T die gleiche Art ist, nicht streng Subtyp voneinander (die richtiger Subtyping wäre).
Für primitive Typen wird in 4.10.1 Subtyping unter Urtyp beschrieben:
Die folgenden Regeln für die direkte geordneter Typ Beziehung zwischen den primitiven Typen definieren:
- double> 1 Schwimmer
- float> 1 lange
- long> 1 int
- int> 1 char
- int> 1 kurz
- kurz> 1 Byte
Mit diesen sind die Überladungsauflösung Regeln sind das Gleiche wie mit C# für diesen speziellen Fall. Die vorherige Erklärung ist anwendbar.
Dies ist, weil lange ist das gleiche wie Int64. Im zweiten Beispiel sind die Methoden identisch. Warum das letzte dauert, weiß ich nicht. Grundsätzlich ist es nicht gut, zwei gleichnamige Methoden mit unterschiedlichen numerischen Eingabetypen zu verwenden. – t00thy
@ t00thy, aber das ist es, wofür Überladung da ist, denselben Methodennamen mit verschiedenen Parametern zu haben, nicht wahr? –
Warum sollten Sie erwarten, dass 'Add (int, float)' hier der bessere Kandidat ist? Was ist los mit lang, lang dann? –