6
votes

Y a-t-il une telle chose que "ne me soucie pas" lors de la contrainte de paramètre générique à une autre interface générique?

J'ai une fonction qui accepte un paramètre générique TD que j'ai besoin de contraindre à une interface générique. Par exemple: xxx

Cependant, nous utilisons de nombreuses IentityDéfinitions différentes: xxx

mais ma fonction défini -onpopuler ne " t Utilisez le deuxième paramètre générique du tout, et cela ne se soucie pas de ce que c'est. Mais il a besoin de gérer tous les des définitions que nous avons en place, maintenant et à l'avenir. Donc, il semble que je suis bloqué créer une nouvelle signature pour définitionPopuler pour chaque paramètre de deuxième générique IentityDefinition que nous avons en place ... sauf si ...

question : y a-t-il une manière que je puisse dire au compilateur que je ne me soucie pas du paramètre de deuxième type? Quelque chose comme une fauve sauvage?

Modifier : J'ai accepté la réponse que j'ai faite parce que c'est la vraie réponse à la question que j'ai posée. Cependant, Cette réponse fournit une excellente solution et est ce que j'ai fini par utiliser pour résoudre le sous-jacent Problème que j'avais - assurez-vous de vérifier!


4 commentaires

Je pense que vous dépassez trop les génériques. Vous devriez penser à refaire votre conception afin qu'ils utilisent moins de génériques. Juste mes 2 cents.


Vous allez parler différemment, lorsque vous avez des méthodes et des classes contenant 5 paramètres génériques (que vous avez besoin de type) et qu'aucun moyen de le refouler correctement.


En fait, l'exemple que j'ai donné a été simplifié à partir de la classe de 5 paramètres Real que nous avons dans notre application. Votre suggestion est donc d'écrire plusieurs classes pour chaque version de la classe que nous avons au lieu d'utiliser des génériques ??


Je suggère de la refonte complète. Quelque chose comme le modèle de visiteur pourrait être meilleur que des tonnes de génériques. Mais je ne sais pas que si je vois tout le problème. Mais cela pourrait être trop pour cela.


4 Réponses :


7
votes

Vous ne pouvez pas instancier un type générique sans spécifier tous les paramètres de type.

Probablement le meilleur que vous puissiez faire est d'ajouter ce paramètre de type non utilisé de l'interface à vos paramètres de type générique: P>

public T DefinitionPopulate<T, TD, DontCare>(IDataReader dr)
    where T: class, new()
    where TD: IEntityDefinition<T, DontCare>, new()


1 commentaires

Yup - Comme je soupçonnais ... merci. :)



3
votes

pas de caractères génériques - vous devrez ajouter un troisième paramètre générique à votre définition, uniquement pour permettre la flexibilité: xxx


2 commentaires

Yup - j'ai commencé à descendre ce chemin, puis pensé "ce ne serait-il pas bien si ..." Mais hélas .. aucun amour. Merci!


Fyi vous et David ont donné essentiellement la même réponse, mais je devais lui donner le chèque parce que sa réponse montrait d'abord (en secondes). Je l'ai fait +1 toi tu.



9
votes

Je crois, dans ce cas, vous devriez avoir une interface ientitydéfinition que tous ceux héritent de, c'est-à-dire: xxx

puis avoir le reste des génériques hériter de là: xxx

Si vous ne pouvez pas changer cela, vous pouvez ajouter un paramètre de type troisième type à votre fonction générique, mais c'est mauvais design, je ' D Dites.


6 commentaires

Ouais - comme vous pouvez suspecter, ce code est dans Heavy Utilisez tout au long de notre grande application interne. Ne peut pas être changé, malheureusement. Semble que le troisième paramètre est le moyen d'aller.


C'est toujours comme ça ... Cependant, je crois toujours que cela se passe contre l'interface les règles ... Les interfaces doivent être le dénominateur le moins courant, si vous n'utilisez pas ce deuxième type dans une implémentation dans certaines implémentations que Utilise l'interface, probablement l'interface n'est pas bien conçue. Cela dit, oui, je comprends comment cela ne peut pas être changé lorsqu'il est répandu sur une grande application (j'ai moi-même de nombreux problèmes comme celui-ci sur mes propres applications :-)).


BTW, Changement de l'interface Devrait N'EST PAS blesser votre implémentation existante ... Toutes les classes existantes implémentaient à la fois le parent et l'interface enfant afin que ce soit simplement une modification de définition (que vous pouvez utiliser pour le nouveau code).


Yup - ce n'est pas une question de savoir à quel point il est difficile de parler techniquement, mais d'une question de convaincre la héléraire des gestionnaires de projet (sans oublier les autres programmeurs) que nous devrions faire un changement radical pour quelque chose qui a été en place depuis des années, juste pour soutenir ma seule petite fonction.


@MichaelBray: Modification d'une interface afin qu'elle hérite d'une autre interface en déplaçant certains de ses membres à cette autre interface exigerait que tout code qui met en œuvre ou utilise cette interface être recompilé, mais ne doit pas nécessiter de modifications au-delà de cela. L'utilisation de l'interface se répandre-t-elle parmi tant d'applications différentes qu'un tel changement serait problématique?


@supercat: non .. et comme il s'avère, je était Capable de convaincre l'équipe de faire ce changement. Ainsi, cela a éliminé ma nécessité pour le type de doncare dans la réponse acceptée. Cependant, je ne m'attends pas à changer la réponse attendue car, même si c'est la solution que j'ai retrouvée, la réponse actuellement acceptée est celle qui répond vraiment à la question que j'ai posée. Je vais éditer la question pour mentionner les gens ici cependant.



0
votes

Répondre à mon propre poste pour les futurs lecteurs après qu'un collègue a souligné quelque chose qui est proche. Ma question originale concernait les paramètres de type générique sur les méthodes, mais si vous essayez de spécifier une valeur par défaut pour une classe, il existe une "sorte de" réponse - héritage.

Pour être clair, ce n'est pas strictement "par défaut". Il ressort plus de méthodes de surcharge et d'appeler la version la plus spécifique, mais comme la surcharge de la méthode, elle atteint essentiellement le même résultat. P>

Par exemple: P>

public class Parent<T1, T2>() { ... }
public class Parent<T1> : Parent<T1, int> { ... }


4 commentaires

Si vous n'utilisez pas ce INT du tout, je devrais insister sur le fait qu'il s'agit d'un mode de programmation extrêmement horrible extrêmement horrible (je pense que même de la solution acceptée à ce sujet. Question) Et si j'étais en charge de tout programmeur qui l'a fait, il aurait probablement de bonnes réponses de cela.


Merci ... clairement votre solution est la meilleure réponse au problème que j'étais avoir (j'ai maintenant noté cela dans la question), mais la réponse acceptée est celle qui répond à la question que je < J'ai demandé . Félicitations pour voir le vrai problème. Cependant, à votre propos, voudriez-vous clarifier pourquoi vous pensez cette technique est si horrible? Ce n'est pas que le int n'est pas utilisé, c'est simplement que nous fournissons une option où le programmeur n'a pas à spécifier t2 tout le temps. Comment est-ce différent de fournir une valeur par défaut pour un paramètre de méthode?


C'est mon adpinion (et juste mon adpinion) que le code ne doit pas être fait "confortable", mais "bon". L'ajout d'un paramètre de type qui n'est pas utilisé du tout n'est que de mauvais code (à nouveau, IMHO), ce qui conduit à d'éventuels malentendus dans le futur (je peux voir un baccalauréat dans un proche avenir sur ce code et qu'il passe des heures à essayer de comprendre pourquoi Il y avait un paramètre de type int non utilisé). Je penserais la même chose à propos de l'ajout d'une valeur par défaut pour un paramètre inutilisé: s'il est inutilisé, il suffit de N'ajoutez pas ce paramètre , ne faites pas de valeur par défaut.


PS: BTW, je ne m'attendais pas à changer la réponse, je spécifiais simplement mon adpinion sur la réponse ... désolé si cela ressemblait autrement