Comment faire pour retourner un objet générique à partir d'une méthode en C#
J'ai un problème similaire à cette question seulement, je ne suis pas d'apprentissage génériques veux donc une solution pratique et ma méthode est de retour plus qu'un int
ou un double
.
J'ai une fonction qui peut retourner un objet (à partir d'un ensemble de classes qui ne sont pas liés les uns aux autres), basée sur la saisie de l'utilisateur.
Par exemple si j'ai deux classes suivantes
public class A
{
}
Et
public class B
{
}
Et ma méthode est la suivante:
public Object getObject(int objType)
{
//return appropriate object based on objType (1==A, 2==B);
}
Je peux utiliser des énoncés comme if (getObject(int objType) is A)
dans mon code, mais qui nécessitent beaucoup de if
des déclarations qui n'est pas une bonne solution (à mon humble avis).
Donc je suis à la recherche d'une meilleure solution de conception pour résoudre ce problème. Toutes les suggestions s'il vous plaît?
MODIFIER
Je vais devoir utiliser l'objet retourné depuis un certain temps et peut-être aussi besoin de la passer à un autre mode ou de renvoyer une référence de. Donc attendu à un déplacement de cet objet. Veuillez garder à l'esprit tout en suggérant une approche pour résoudre ce problème.
- Si vous êtes en utilisant .net version 4.0 ont un look dynamique :hanselman.com/blog/...
- Si le problème est ce que votre code d'appel doit faire avec
object
, alors pouvez-vous fournir plus d'informations sur exactement commentA
etB
sont utilisés, et comment ils les mêmes qu'ils sont?
Vous devez vous connecter pour publier un commentaire.
La construction d'un type d'objet différent basé sur une entrée audio comme vous pourriez utiliser le Usine motif de conception.
EDIT: Si vous voulez que les appelants ne pas vérifier le type d'objet, puis le modèle de Fabrique est en train de devenir une option viable en tant que de tirer profit de la polimorphism. Vous retourner l'objet dans une variable de classe de base type et lorsque vous appelez une méthode de la droite de code sera lancé selon le type objet réel.
Si vos types sont indépendants, alors il vaut la peine de voir si vous pouvez leur faire part d'une classe de base, car uing polimorphism est plus elgant façon de résoudre le problème d'un grand changement.
Que sur un switch/case bloquer?
Noter que cela a rien à faire avec les génériques.
MODIFIER
Après avoir lu les commentaires, je vois que ce n'est pas ce dont vous avez besoin après tout. Selon les nouvelles informations, je ne vois que deux façons de faire (un peu) ce que vous avez besoin.
A
etB
hériter (appelons celaC
dans ce cas), et faire de votregetObject
méthode renvoie un objet de C à la place.public T getObject<T>()
. Cela signifie que l'appelant doit envoyer le type de l'objet au lieu de 1 ou 2 dans legetObject
méthode, mais au moins il sait ce qu'il va obtenir en retour.Tant que la méthode retourne
object
, et prend juste un paramètre deint
qui définit le type d'objet à créer, il n'y a aucun moyen que vous pouvez trouver à quel type d'objet que vous obtenez en retour à court de vérification de l'objet lui-même, et si il est de nombreux types d'objets qui peuvent être retournés, ce genre de code va très vite déraper.Si j'ai une classe qui doit retourner un objet et je dois l'obtenir à partir d'un type spécial, j'ai l'habitude ont quelque part un ensemble de paramètres de fonctions dans un dict comme
Dictionary<Type, Func<Type>>
(peut-être avec des paramètres commeFunc<P1, P2, ..., Type>
. Puis-je écrire ces fonctions et de les mettre dans le dictionnaire. Ensuite, vous pouvez facilement obtenir le bon objet en dehors d'elle.Une autre approche (si vous avez accès au code source des objets et qu'ils ont quelque chose à partager) vous pouvez ajouter une Interface pour eux et puis créer un
List<MyInterface>
. Si vos objets sont dans le bon ordre (si vous souhaitez utiliser votreint objType
), vous pouvez tout simplement obtenir le droit en appelantmyList[index]
.Si vous voulez juste pour obtenir une nouvelle instance de la classe de fournisseur, vous pouvez utiliser cette fonction.
Pas besoin de mentionner
objectType
Pour info, vous êtes à la mise en œuvre d'un type de Modèle de fabrique.
En général, il y a seulement deux manières d'éviter un interrupteur, lorsqu'il s'agit d'une fonction qui varie en fonction du comportement de type:
Dans votre exemple, l'entrée de l'usine est complètement indépendant de type, de sorte que vous ne pouvez pas utiliser le polymorphisme.
Si vous pouviez demander à l'utilisateur de passer un type personnalisé, alors vous pouvez prendre avantage de polymorphisme dans votre usine:
Si
A
etB
sont tout comme les uns les autres, alors vous devriez vraiment faire une classe de base commune pour eux, ou si vous ne pouvez pas toucher que le code, utilisez la Adaptateur motif d'avoir plus de 3 classes, qui ont la hiérarchie correcte.Si elles ne sont pas du tout les uns des autres, et vous devez avoir
int
comme l'entrée de votre méthode de fabrique, puis un interrupteur, si/d'autre-si la chaîne, ou dictionnaire est votre seule option:Ou
Ou
Ce qui est mauvais dans votre approche - client code de toute façon faut savoir à quel type d'objet retourné par cette méthode (il n'y a pas de polymorphisme, de sorte que vous ne pouvez pas retourner un objet de la classe de base type):
BTW son mieux pour utiliser Enum pour définir le type de l'objet, plutôt que int.
Donc, en tant que client sait quelle méthode sera de retour, pourquoi ne pas créer deux méthodes distinctes pour les clients à utiliser?
Si ces objets ont le même but, il est préférable d'utiliser l'héritage de formulaire de la classe de base ici:
Je voudrais utiliser Adeel réponse en combinaison avec un Dictionnaire pour stocker la combinaison de Types avec les services de renseignements. Puisque vous utilisez ints pour identifier le type que vous avez besoin d'une forme de correspondance entre les deux de toute façon.
Bien vous avez vraiment utiliser si consolidés. Je pourrais faire quelque chose comme:
Cependant, vous avez un très étrange méthode appelée getObejct(). Depuis, vous devez passer un int pour obtenir le type résultant; cela implique que vous connaissez déjà le type d'objet que vous souhaitez. Ainsi, lorsque vous voulez un Un faire "var a = (a) getObject(1)" et quand vous voulez a B faire " var b = (b) getObject(2)".