2012-07-25 1 views
0

Dites que j'ai une méthode surchargée, par exemple void PrintInfo(Person) et void PrintInfo(Item), et ainsi de suite. J'essaie d'invoquer ces méthodes en passant un objet. Je me demande pourquoi il me donne une erreur quand je fais ceci; toutes les classes ne sont-elles pas héritées de l'objet? Je veux éviter de faire une instruction if/switch où je vérifie quel type est l'objet avant d'appeler la méthode appropriée.Transformer l'objet en type approprié pour les méthodes surchargées

Selon vous, quelle est la meilleure approche dans ce cas?

+2

Vous recherchez le modèle 'dynamic' ou le modèle de visiteur. – SLaks

Répondre

2

Tous les Person s sont object s, mais pas tous les object s sont Person s. Pour cette raison, vous pouvez passer un Person à une méthode qui accepte un object mais vous ne pouvez pas passer un object à une méthode qui nécessite un Person.

Il semble que vous ayez quelques fonctionnalités communes entre différents objets que vous souhaitez utiliser. Étant donné cela, il serait préférable de trouver soit un ancêtre commun qui a toutes les fonctionnalités dont vous avez besoin, ou une interface qu'ils implémentent tous (qui fournit à nouveau tout ce dont vous avez besoin).

Dans le cas de l'impression, il se peut que vous ayez besoin de la méthode ToString. Dans ce cas, vous pouvez simplement demander à la méthode d'accepter un object et d'appeler le ToString. (C'est ce que beaucoup de méthodes d'impression font, comme Console.WriteLine.

1

Vous devez comprendre que parce que C# est un langage typé statiquement (sauf dynamic) la surcharge particulière qui est choisie (appelée résolution de surcharge) est déterminée au moment de la compilation , pas le temps d'exécution cela signifie que le compilateur doit être en mesure de déterminer avec certitude de quel type votre argument est Tenir compte:..

Object foo; 
foo = "String"; 
foo = 5; 
PrintInfo(foo); // Which overload of printinfo should be called? The compiler doesn't know! 

Il y a quelques façons de résoudre this- faire foo de type dynamic est de un que provoquera la surcharge correcte à choisir au moment de la compilation. c'est-à-dire que vous perdez la sécurité du type - si vous ne disposez pas d'une surcharge appropriée pour ce type, votre application sera toujours compilée mais se bloquera lorsque vous essaierez d'imprimer les informations du type non supporté.

Une approche sans doute meilleure est de s'assurer que foo est toujours du type correct, plutôt que seulement Object.

Comme le suggère @Servy, une autre approche consiste à attacher le comportement au type lui-même. Vous pouvez, par exemple, faire une interface IHasPrintInfo:

public interface IHasPrintInfo { String PrintInfo { get; } } 

et mettre en œuvre cette interface sur tous les éléments dont les informations vous pouvez imprimer. Ensuite, votre fonction PrintInfo peut simplement prendre un IPrintInfo:

public void PrintInfo(IPrintInfo info) { 
    Console.WriteLine(info.PrintInfo); 
} 
0

ici son ambiguïté pour le compilateur; Le compilateur ne peut pas savoir quelle version de la méthode (personne/objet) vous êtes appelé à appeler.

Questions connexes