c# methode static - Pourquoi le compilateur C # ne corrige pas le code où une méthode statique appelle une méthode d'instance?




2 Answers

Pour une raison quelconque, la résolution de surcharge trouve toujours la meilleure correspondance avant de rechercher statique ou non statique. Veuillez essayer ce code avec tous les types statiques:

class SillyStuff
{
  static void SameName(object o) { }
  void SameName(string s) { }

  public static void Test()
  {
    SameName("Hi mom");
  }
}

Cela ne compilera pas car la meilleure surcharge est celle qui prend une string . Mais bon, c'est une méthode d'instance, donc compilateur se plaint (au lieu de prendre la deuxième meilleure surcharge).

Addition: Donc je pense que l'explication de l'exemple dynamic de la Question Originale est que, pour être cohérent, quand les types sont dynamiques, nous trouvons d' abord la meilleure surcharge (vérifier seulement le numéro de paramètre et les types de paramètres etc. non statique), et seulement ensuite vérifier pour statique. Mais cela signifie que le contrôle statique doit attendre jusqu'à l'exécution. D'où le comportement observé.

Ajout tardif: Un peu de contexte sur pourquoi ils ont choisi de faire des choses cet ordre drôle peut être déduit de ce blog par Eric Lippert .

definition classe

Le code suivant a une méthode statique, Foo() , appelant une méthode d'instance, Bar() :

public sealed class Example
{
    int count;

    public static void Foo( dynamic x )
    {
        Bar(x);
    }

    void Bar( dynamic x )
    {
        count++;
    }
}

Il compile sans erreur * mais génère une exception de liant d'exécution au moment de l'exécution. Suppression du paramètre dynamique à ces méthodes provoque une erreur de compilation, comme prévu.

Alors pourquoi avoir un paramètre dynamique permet de compiler le code? ReSharper ne le montre pas non plus comme une erreur.

Édition 1: * dans Visual Studio 2008

Edit 2: ajouté sealed car il est possible qu'une sous-classe puisse contenir une méthode Bar(...) statique. Même la version scellée compile lorsqu'il n'est pas possible qu'une méthode autre que la méthode d'instance puisse être appelée lors de l'exécution.




L'expression "dynamique" sera liée pendant l'exécution, donc si vous définissez une méthode statique avec la bonne signature ou une méthode d'instance, le compilateur ne la vérifie pas.

La "bonne" méthode sera déterminée pendant l'exécution. Le compilateur ne peut pas savoir s'il existe une méthode valide pendant l'exécution.

Le mot clé "dynamic" est défini pour les langages dynamiques et de script, où la méthode peut être définie à tout moment, même pendant l'exécution. Trucs fous

Voici un exemple qui gère les ints mais pas les chaînes, à cause de la méthode est sur l'instance.

class Program {
    static void Main(string[] args) {
        Example.Foo(1234);
        Example.Foo("1234");
    }
}
public class Example {
    int count;

    public static void Foo(dynamic x) {
        Bar(x);
    }

    public static void Bar(int a) {
        Console.WriteLine(a);
    }

    void Bar(dynamic x) {
        count++;
    }
}

Vous pouvez ajouter une méthode pour gérer tous les appels "incorrects", qui n'ont pas pu être traités

public class Example {
    int count;

    public static void Foo(dynamic x) {
        Bar(x);
    }

    public static void Bar<T>(T a) {
        Console.WriteLine("Error handling:" + a);
    }

    public static void Bar(int a) {
        Console.WriteLine(a);
    }

    void Bar(dynamic x) {
        count++;
    }
}



Related