2010-08-16 24 views
9

Quelles sont les règles concernant la surcharge de fonction?C# règles de surcharge de fonction

je le code suivant:

public T genericFunc<T>() where T : Component, new() 
{ 
    T result = new T(); 
    overloadedFunction(result); 
} 

private overloadedFunction (Component c) // catch all function 

private overloadedFunction (DerivedFromComponent dfc) // specific function 

quand j'appelle le code ci-dessus avec:

genericFunc<DerivedFromComponent>(); 

Je pense que le overloadedFunction plus spécifique à appeler, mais la capture toutes les fonctions est appelée à la place , Pourquoi est-ce?. En passant par le code ci-dessus le type T est en effet DerivedFromComponent, je pensais que le CLR choisissait la meilleure correspondance possible à l'exécution!

Répondre

14

Le compilateur effectue une résolution de surcharge dans genericFunclorsque cette méthode est compilée. À ce stade, il ne sait pas quel argument de type vous allez fournir, donc il sait seulement qu'il peut appeler la première de vos surcharges. Votre exemple utilisant des génériques rend la vie plus compliquée, mais les surcharges sont toujours résolues au moment de la compilation (en supposant que vous n'utilisiez pas dynamic).

Un exemple simple de ne pas utiliser les médicaments génériques:

void Foo(string text) { } 
void Foo(object o) {} 
... 
object x = "this is a string"; 
Foo(x); 

appelleraient la deuxième surcharge, car le type de xcompilation est juste objet.

Pour en savoir plus à ce sujet, lisez mes article on overloading récentes.

3

Jon Skeet est juste sur le fait que la résolution de surcharge est déterminée au moment de la compilation. Je pensais ajouter une autre réponse qui n'était pas le point de votre question mais intéressante à noter néanmoins.

En C# 4, le mot-clé dynamique peut être utilisé pour reporter la résolution de surcharge jusqu'à l'exécution. Considérons l'extrait suivant qui imprime:

Base! 
Derived! 


class Base { 
} 

class Derived : Base { 
} 

void DoSomething(Base x) { 
    Console.WriteLine("Base!"); 
} 

void DoSomething(Derived x) { 
    Console.WriteLine("Derived!"); 
} 

void DoSomething<T>() where T: Base, new() { 
    dynamic x = new T(); 
    DoSomething(x); 
} 

void Main() 
{ 
    DoSomething<Base>(); 
    DoSomething<Derived>(); 
} 
+0

Doh, et dans le temps qu'il m'a fallu pour écrire ce Jon Skeet a également noté dynamique. – Josh

+0

Si seulement je pouvais obtenir la gestion de printemps pour une nouvelle copie brillante de VS2010 tous mes problèmes s'évaporeraient ... mais hélas je suis coincé avec .NET 3.5 et VS2008! –

+2

Pour être honnête, je ne recommanderais pas d'utiliser le code ci-dessus pour résoudre le problème. Ce n'est pas un très bon exemple d'utilisation justifiée pour la résolution dynamique. – Josh