2010-02-02 9 views
1

J'ai lu que ToString() utilise la réflexion (bien qu'il devrait simplement mettre des guillemets autour de l'objet sur lequel il est appelé, donc je ne sais pas où/pourquoi il peut utiliser la réflexion). Y a-t-il une preuve de cela? Et y a-t-il une pénalité de performance pour l'appel de .ToString() (peut-être devrais-je appeler Convert.ToString()?)?L'appel de ToString() gotchas

+3

"Placer des guillemets autour de l'objet sur lequel il est appelé"? Qu'est-ce que tu veux dire par là ... J'ai l'impression que c'est une mauvaise conception ... – Romain

+0

Je pense qu'il veut dire que si tu avais un objet appelé duka et que tu avais duka d = new duka(); d.ToString() retournerait 'duka' – taylonr

+0

@taylonr: Si c'était le cas, cela demanderait * certainement * une réflexion. –

Répondre

4

Si vous ne remplacez pas la méthode ToString(), vous finissez par appeler Object.ToString(), dont la mise en œuvre ressemble à quelque chose comme ceci:

public virtual string ToString() 
{ 
    return this.GetType().ToString(); 
} 

[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical] 
public extern Type GetType(); 

La méthode ne pas simplement « mettre des guillemets autour de l'objet, il est appelé sur". Afin d'atteindre ce résultat, il faut pensivement obtenir les informations de type d'exécution et appelez ToString() à ce sujet, qui à son tour ressemble à ceci:

public override string ToString() 
{ 
    return ("Type: " + this.Name); 
} 

Chaque fois que vous passez par réflexion pour quelque chose il y a un peu d'une performance pénalité, mais dans ce cas probablement pas assez grande pour vraiment compter - à moins que vous le fassiez à l'intérieur d'une boucle très serrée et très grande.

Voyez-vous un problème de performances? Qu'est-ce que vous essayez d'accomplir qui vous amène à vouloir appeler Object.ToString() plutôt que d'appeler une version substituée que vous fournissez?

+0

Merci. Bon détail dans votre réponse +1 – duka

+0

btw c'est juste une question théorique, pas de cas d'utilisation. – duka

3

Je pense que si vous ne surchargez pas ToString() c'est où il finit par utiliser la réflexion.

Si vous aviez:

public class SomeObject 
{ 
    public void SomeMethod(); 
} 

void program 
{ 
    SomeObject o = new SomeObject(); 
    Console.WriteLine(o.ToString()); 
} 

Vous devez utiliser la réflexion pour savoir quel type d'objet est o. Maintenant, si vous surchargez ToString() ce que vous devez faire pour avoir une représentation de chaîne significative, alors le code que vous écrivez sera appelé directement sans réflexion.

+8

En fait, l'implémentation par défaut n'utilise pas de réflexion. Il appelle GetType() qui est marqué comme InternalCall par exemple. fonctionnalité intégrée directement dans le CLR. Donc, même ce chemin de code ne devrait pas atteindre les pénalités de performance basées sur la réflexion. –