2015-09-05 13 views
5

Ich führte die folgenden Methoden in C#.Methode überladen in C# und Java

public float Add(float num1, long num2) 
{ 
    Console.WriteLine("method 1"); 
    return 0; 
} 
public float Add(int num1, float num2) 
{ 
    Console.WriteLine("method 2"); 
    return 0; 
} 

Hier wird, wenn ich Add(1,1) nennen, gibt es Mehrdeutigkeit. Nun lassen Sie mich Position float und long in dem ersten Verfahren auszutauschen, wie folgt:

public float Add(long num1, float num2) 
{ 
    Console.WriteLine("method 1"); 
    return 0; 
} 
public float Add(int num1, float num2) 
{ 
    Console.WriteLine("method 2"); 
    return 0; 
} 

Jetzt druckt „Methode 2“ als Ausgabe. Was ist der Grund für die Mehrdeutigkeit im ersten Fall?

Und wenn ich folgende zwei Methoden in meinem Code schreiben:

public float Add(long num1, long num2) 
{ 
    Console.WriteLine("method 1"); 
    return 0; 
} 
public float Add(int num1, float num2) 
{ 
    Console.WriteLine("method 2"); 
    return 0; 
} 

Auf Add(1,1) Aufruf, gibt es Mehrdeutigkeit Fehler. Warum geht es nicht für die beste Übereinstimmung, die die zweite Methode ist (mit int und float)? Nach meiner Meinung hätte es Methode 2 als Ausgabe geben sollen.

+0

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

+0

@ t00thy, aber das ist es, wofür Überladung da ist, denselben Methodennamen mit verschiedenen Parametern zu haben, nicht wahr? –

+0

Warum sollten Sie erwarten, dass 'Add (int, float)' hier der bessere Kandidat ist? Was ist los mit lang, lang dann? –

Antwort

9

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.

    1

    In diesem Fall wird der Compiler-Look für die Methode, die am nächsten die Eingangsgröße entspricht (en)

    public float Add(float num1, long num2) 
    { 
        Console.WriteLine("method 1"); 
        return 0; 
    } 
    public float Add(int num1, float num2) 
    { 
        Console.WriteLine("method 2"); 
        return 0; 
    } 
    

    Add (1,1) Diese Methode ist nicht klar, welche Version wählen soll, so dass diese für die Lösung Problem (float oder int im ersten Parameter, lang oder schweben in zweite) Sie Art von einem der Eingänge Parameter in Methode

    Add(1F, 1); 
        Add(1, 1F); 
    

    Aber folgenden Code angeben müssen, Compiler betrachten int-Typ als die am nächsten matche für Nummer 1 im ersten Methodenparameter

    public float Add(long num1, float num2) 
    { 
        Console.WriteLine("method 1"); 
        return 0; 
    } 
    public float Add(int num1, float num2) 
    { 
        Console.WriteLine("method 2"); 
        return 0; 
    } 
    

    so Wenn Sie die erste Methode aufrufen wollen, sollten Sie dies tun

    Add(1L, 1); 
    

    Und für den dritten Teil von Ihnen Code

    public float Add(long num1, long num2) 
    { 
        Console.WriteLine("method 1"); 
        return 0; 
    } 
    public float Add(int num1, float num2) 
    { 
        Console.WriteLine("method 2"); 
        return 0; 
    } 
    

    wieder ist es nicht klar, welche Version complier verwenden sollten Wegen des zweiten Eingabeparameters in Ihrer Methode (float oder long) müssen Sie zur Lösung dieses Problems den Eingang

    angeben
    +0

    Danke @Arash, aber ich möchte wissen, wie die Methoden im Falle der Methode Überladung gewählt werden. Bitte sag mir das Konzept. –

    +0

    @GauravJainn as Eric Lippert sagte: Die grundlegende Skizze des Prozesses ist: Sobald wir eine Reihe von geeigneten Kandidaten haben, führen Sie mehr Filter auf sie, um die einzig beste zu bestimmen.Die Filter sind ziemlich kompliziert. Zum Beispiel ist eine Methode, die ursprünglich in einem abgeleiteten Typ deklariert wurde, immer besser als eine Methode, die ursprünglich in einem weniger abgeleiteten Typ deklariert wurde. Eine Methode, bei der die Argumenttypen genau mit den Parametertypen übereinstimmen, ist besser als eine, bei der es ungenaue Übereinstimmungen gibt. Und so weiter. Siehe die Spezifikation für die genauen Regeln. Http://stackoverflow.com/questions/6125585/c-sharp-method-resolution-long-vs-int – Arash