39 votes

Résolution de la méthode C #, long vs int

 class foo
{
  public void bar(int i) { ... };
  public void bar(long i) { ... };
}


foo.bar(10);
 

Je m'attendrais à ce que ce code me donne une erreur, ou du moins un avertissement, mais pas tant que ça ...

Quelle version de bar () est appelée et pourquoi?

54voto

Kevin Points 57797

L'int de la version de la barre est appelé, parce qu' 10 est un entier littéral et le compilateur va chercher la méthode la plus proche correspond à la variable d'entrée(s). Pour appeler la version longue, vous aurez besoin de spécifier un long littéral comme suit: foo.bar(10L);

Voici un post par Eric Lippert sur beaucoup plus compliqué versions de la surcharge de méthode. J'avais essayer de l'expliquer, mais il fait un bien meilleur travail et je ne pourrais le faire: http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx

à partir de C# 4.0 Spécifications:

La surcharge de méthode permet à plusieurs les méthodes de la même classe à avoir le même nom aussi longtemps que ils ont unique les signatures. Lors de la compilation d'un l'invocation d'une méthode surchargée, le compilateur utilise une résolution de surcharge pour déterminer la méthode à invoquer. Résolution de surcharge trouve le une méthode qui correspond le mieux à la arguments ou signale une erreur si pas de meilleur match peut être trouvé. L' l'exemple suivant montre la surcharge la résolution en vigueur. Le commentaire de chaque invocation de la méthode main indique la méthode est en fait invoquée.

 class Test {   
      static void F() {
        Console.WriteLine("F()");   
      }     
      static void F(object x) {
        Console.WriteLine("F(object)");     
      }
      static void F(int x) {
        Console.WriteLine("F(int)");    
      }
      static void F(double x) {
        Console.WriteLine("F(double)");     
      }
      static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");   
      }
      static void F(double x, double y) {
        Console.WriteLine("F(double,double)");  
      }     

      static void Main() {
        F();                // Invokes F()
        F(1);           // Invokes F(int)
        F(1.0);         // Invokes F(double)
        F("abc");       // Invokes F(object)
        F((double)1);       // Invokes F(double)
        F((object)1);       // Invokes F(object)
        F<int>(1);      // Invokes F<T>(T)
        F(1, 1);        // Invokes F(double, double)
      } 
}

Comme le montre l'exemple, un particulier la méthode peut toujours être sélectionné par explicitement casting les arguments pour l'exacte des types de paramètres et/ou explicitement, en fournissant des arguments de type.

12voto

Eric Lippert Points 300275

Kevin dit, il y a une surcharge de la procédure de résolution. La base de l'esquisse du processus est le suivant:

  • Identifier tous les accessible candidat méthodes, éventuellement à l'aide de l'inférence de type sur les méthodes génériques
  • Filtrer les inapplicable méthodes; c'est à dire les méthodes qui ne peuvent pas travailler parce que les arguments ne pas convertir implicitement les types de paramètres.
  • Une fois que nous avons un ensemble des lois applicables sur les candidats, exécutez plus de filtres pour déterminer l'unique meilleur.

Les filtres sont assez compliqué. Par exemple, une méthode a été initialement déclarée dans un plus type dérivé est toujours mieux qu'une méthode initialement déclaré au moins un type dérivé. Une méthode où l'argument types correspondent exactement aux types de paramètres est meilleure que celle où il y a des imprécisions de matchs. Et ainsi de suite. Voir les spécifications pour les règles exactes.

Dans votre exemple, le "betterness" l'algorithme est simple. La correspondance exacte de int int est mieux que les imprécisions de match de l'int de long.

4voto

abcdefghi Points 2149

Je dirais que si vous dépassez la limite inférieure

 -2,147,483,648 to 2,147,483,647
 

le contrôle ira à long

Plage pour long

 –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
 

Valeur maximale pour int

 foo.bar(-2147483648);
 

ou

 foo.bar(2147483648);
 

Long aura le contrôle si nous dépassons la valeur de 2147483648

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X