2009-07-15 8 views
7

J'ai écrit une méthode d'extension pour String pour obtenir un argument char, string.Remove(char). Mais quand j'ai utilisé ceci, il a appelé la méthode par défaut string.Remove(int).Résolution de méthode d'extension

La présence d'une méthode réelle ne devrait-elle pas avoir une priorité plus élevée qu'une conversion implicite?

Répondre

9

Les méthodes d'instance ont priorité sur les méthodes d'extension. Votre observation est la preuve de la même chose. Lors de la résolution de la méthode à appeler, il choisira toujours une méthode d'instance correspondante sur une méthode d'extension ... qui est intuitive d'une certaine manière.

paraphrasés de C# en profondeur,

Lorsque le compilateur voit que vous êtes essayer d'appeler une méthode qui ressemble comme une méthode d'instance, mais est incapable d'en trouver un, il recherche alors méthodes d'extension (qui sont visibles basé sur vos using directives). En cas de plusieurs candidats comme la méthode d'extension cible , l'une avec « meilleure conversion » similaire à surcharge (par exemple si iChild et IBase ont tous deux une méthode d'extension similaire défini .. IChild.ExtensionMethod est choisi)

Un code caché pourrait aussi être dit que TypeA n'avait pas de méthode SecretMethod comme méthode d'instance dans Libv1.0. Donc vous écrivez une méthode d'extension SecretMethod. Si l'auteur introduit une méthode d'instance du même nom et de la même signature dans v2.0 (sans le paramètre this), et recompilez votre source avec le dernier-n-plus grand Libv2.0, tous les appels existants à la méthode d'extension serait maintenant silencieusement routé vers la nouvelle méthode d'instance.

+0

Ouais mais au moins il n'y a pas de méthode directe, juste une qui nécessite une distribution implicite. Donc je m'attendais à ce qu'il cherche une méthode directe. –

+4

"tous les appels existants à la méthode d'extension seraient maintenant routés vers la nouvelle méthode d'instance." - Notez que cela ne compte que lors de la recompilation. Un appel d'extension est simplement traduit dans un appel de méthode statique. – Dykam

+1

Le compilateur fera de son mieux pour satisfaire la requête de résolution de méthode avec une méthode d'instance - en utilisant des conversions implicites si nécessaire. Il ne regarde les méthodes d'extension que s'il ne le peut pas. Essayer aussi les lancements implicites pour trouver une méthode d'instance est std. comportement. Par exemple, MyFunc ('A') résoudra un void statique MyFunc (int a) avec a = 65. Vous pouvez éviter tout cela en définissant simplement votre méthode d'extension à un nom qui n'est pas pris - mais vous ne pouvez jamais être sûr para. – Gishu

2

Ce comportement est correct. La raison en est que l'introduction d'une méthode d'extension ne devrait pas changer la façon dont le code existant s'exécute. Le code doit se comporter exactement de la même manière avec ou sans cette méthode d'extension "superflue". Cela peut sembler contre-intuitif dans certains cas (comme le vôtre), mais cela arrive pour une raison.

Questions connexes