-2
votes

C # Covariance sur les méthodes génériques

en Java, je peux facilement écrire: xxx

Le code ci-dessus compile lorsqu'il est placé à l'intérieur d'une classe (Ignorer les modificateurs, etc.).

Le but est d'écrire une fonction combine qui prend deux iEnumerable s de types de type A et B potentiellement différents, qui héritent de certains T. Le compilateur doit déduire le type de t et retourner un ienumerable sans que je doive spécifier explicitement n'importe quel type dans l'appel de la fonction.

Comment ferais-je cela en C #?


3 commentaires

Utilisez le modificateur OUT : docs.microsoft.com/en-us/dotnet/cshaarp/language-référence/...


@UnholysHeep out ne fonctionne pas sur les méthodes, uniquement sur les types. D'où ma confusion.


@Dracam Ce cas ne peut pas être automatiquement résolu par le compilateur. Si B et C implémente 2 interfaces (disons A1 et A2 ) Quel devrait être le type de retour de cette méthode, ienumerable , ienumerable ...? Aussi, si B et c hériter d'une classe de base A qui hérite de A0 , si le type de retour être ienumerable , ienumerable ...?


3 Réponses :


1
votes

Vous pouvez faire la même chose en C #, voir ci-dessous. XXX


Le compilateur doit déduire le type de t et renvoyer un ienumerable sans que je dois spécifier explicitement n'importe quel type dans l'appel de la fonction.

Ce n'est pas possible, vous devrez spécifier le type commun pour t .


5 commentaires

Savez-vous que si vous voulez être possible dans une version future?


@Dracam - J'en doute que ce serait. Réfléchissez également à plusieurs implémentations d'interface où plusieurs interfaces communes pourraient exister, le compilateur devrait deviner lequel était destiné.


@ VC74 Vous êtes correct. Igor fait exactement cela dans son exemple, mais ma déduction de type bien désirée ne fonctionne pas


@Igor Certains systèmes de type tels que ceux de Java et Scala rendent le travail d'inférence, au moins avec des classes de base (non des interfaces). Je me demande si cela a à voir avec le type Erasure ..


@DRACAM - Votre meilleur pari serait de voir si @ ericlippert peut jeter un coup d'œil à la question. Je crois qu'il a mis en œuvre / conçu de la covariance dans .NET afin qu'il puisse vous dire si c'était quelque chose qui serait pris en compte dans une version future ou comment elle se compare à Java exactement.



1
votes

Non, l'algorithme d'inférence du type du compilateur ne montez pas les collines à la recherche d'un type de base commun, et ce n'est pas quelque chose qui ne s'applique qu'aux paramètres de type générique. Cela ne fonctionnera pas non plus:

var foo = someCondition ? a : b //asume this is legal and resolves type to IFoo


4 commentaires

Je vois votre point avec les conversions et pourquoi ils sont délicats, mais ce qui ne va pas dans la recherche de la base de base de la hiérarchie? Lorsque j'essaie de combiner deux listes de types non liés, je voudrais bien sûr attendre un autre


@Dracam qui pourrait également être une erreur dans laquelle vous vous attendez à un autre type déduit et que le code compile en supposant que vous souhaitez objet . En outre, la quantité d'erreurs ambigeuses serait énorme; Que se passe-t-il si deux conversions sont applicables? Les conversions de référence doivent-elles venir avant les conversions définies par l'utilisateur? Si une conversion définie par l'utilisateur précède deux conversions de référence? etc., etc. Les choses entières se transforment en désordre difficile à comprendre et à prédire. Le chemin C # est beaucoup plus facile à comprendre.


@Dracam également le mode de traitement des choses évite les changements inattendus. Voir la mise à jour.


@Inbetween quelques points valides, merci. Je suppose que je vais juste devoir m'habituer à la méthode prudente C # de faire des choses



0
votes

Cela fonctionne si vous ne comptez pas sur l'inférence de type et spécifiez entièrement tous les types de la fonction: xxx

grâce à @Igor pour la majeure partie de la saisie de cette < / p>


0 commentaires