Quelle est la différence entre un appel un délégué directement, à l'aide de DynamicInvoke, et à l'aide de DynamicInvokeImpl?
Les docs pour les deux DynamicInvoke et DynamicInvokeImpl dire:
Dynamiquement invoque (tardive) de la
méthode représentée par le courant
délégué.
Je remarque que DynamicInvoke et DynamicInvokeImpl prendre un tableau d'objets au lieu d'une liste d'arguments (qui est la tardive de la partie je suppose). Mais est-ce la seule différence? Et quelle est la différence entre DynamicInvoke et DynamicInvokeImpl.
- Ne voulez-vous pas accepter une réponse ici? Je sais que la question est assez vieux maintenant, mais j'ai été irritée qu'il n'y a toujours pas de réponse a accepté alors qu'il existe de bons candidats.
Vous devez vous connecter pour publier un commentaire.
La principale différence entre l'appelant directement (ce qui est à court de main pour
Invoke(...)
) et à l'aide deDynamicInvoke
est de la performance, un facteur de plus de *700 par ma mesure (ci-dessous).Avec l'direct/
Invoke
approche, les arguments sont déjà pré-validé par la signature de la méthode, et le code existe déjà à passer à celles de la méthode directement (je dirais "qu'IL", mais il me semble que le runtime fournit directement, sans tout IL). AvecDynamicInvoke
il a besoin de les vérifier à partir de la matrice par la réflexion (c'est à dire sont-ils appropriés pour cet appel, ont-ils besoin d'unboxing, etc); c'est lent (si vous l'utilisez dans une boucle), et doit être évitée autant que possible.Exemple; les résultats de la première (j'ai augmenté la
LOOP
compter de la précédente édition, pour donner un bon de comparaison):Avec le code:
Par coïncidence, j'ai trouvé une autre différence.
Si
Invoke
déclenche une exception il peut être pris par le type d'exception.Cependant
DynamicInvoke
jette unTargetInvokationException
. Voici une petite démo:Tandis que le second test passe au vert, le premier est confronté à un TargetInvokationException.
Il n'y a vraiment aucune différence fonctionnelle entre les deux. si vous tirez la mise en œuvre dans le réflecteur, vous remarquerez que DynamicInvoke appelle juste DynamicInvokeImpl avec le même ensemble d'arguments. Pas une validation supplémentaire est fait et c'est un non-méthode virtuelle, donc il n'y a aucune chance pour que le comportement de l'être changé par une classe dérivée. DynamicInvokeImpl est une méthode virtuelle où tout le travail est fait.