1
votes

Contrainte de classe de méthode générique d'observation

Existe-t-il un moyen de stocker IReturn ... où T: class, IFeatureX dans le type de variable IReturn ou pouvez-vous expliquer pourquoi cela ne peut pas être fait?


Disons que j'ai un constructeur de conteneur:

public static ContainerX CreateInstance<T>(IReturn<T> instance) 
  where T : class, IFeatureX => new ContainerX { Body = instance };

Je veux dire que IFeatureX étend aussi class , je ont essayé de changer le constructeur en privé et d'utiliser:

public ContainerX(IReturn<IFeatureX> body) : this()
{
    Body = body;
}

Cependant c # ne sait pas que IReturn ... où T: class, IFeatureX code > est IReturn .

Il semble que je ne puisse pas le lancer ou le lancer en toute sécurité.

Je ne peux pas utiliser object ou dynamic car IFeatureX est en fait IProtobufBody et c'est un interface d'étiquette que j'utilise pour faire un test d'intégration garantit que tous les assemblys qui stockent des instances dans le conteneur ont un contrat protobuf défini.


2 commentaires

IFeatureX => nouveau ContainerX {Body = instance}; est sûrement quelque chose qui est évalué au moment de l'exécution , alors que les génériques sont une fonctionnalité à la compilation . Que feriez-vous exactement avec cette mission? Oubliez simplement la nouvelle partie. Quoi qu'il en soit, IFeature est un très mauvais nom pour une classe. La plupart des gens interpréteraient le premier I comme un indicateur d'une interface.


@HimBromBeere comme je l'ai mentionné, j'ai remplacé IProtobufBody par IFeature afin qu'il ne détourne pas l'attention, de la même manière que ContainerX est en fait un message RabbitMq stockant une demande de servicestack, une "promesse" de retourner une réponse.


3 Réponses :


0
votes

Il vous suffit de rendre IReturn covariant en le déclarant comme IReturn . Vous pouvez en savoir plus sur la covariance et la contravariance ici .


0 commentaires

0
votes

Il s'agit d'un problème de covariance et de contravariance ( voir ici ).

Disons que vous avez une classe appelée Dog qui hérite de Animal , considérez le code suivant:

List<Dog> l = new List<Dog>();
List<Animal> la = l;
la.Add(new Giraffe()); // this is not allowed

Cet exemple montre pourquoi il n'est pas autorisé par défaut.

Il y a les mots-clés in et out qui vous permettent utilisez la contravariance et la covariance comme IReturn ou IReturn .

Lorsque vous utilisez in , alors vous pouvez stocker un objet IReturn dans une variable de type IReturn et définir des fonctions dans IReturn qui utilisent T comme variable d'entrée Type.

Lorsque vous utilisez out , vous pouvez stocker un objet IReturn dans une variable de type IReturn et définissez les fonctions dans IReturn qui utilisez T comme type de retour.

Si vous avez besoin que T soit un type de variable d'entrée dans certaines fonctions et un type de retour dans d'autres fonctions, alors vous ne peut fonctionner qu'avec la classe exacte.


0 commentaires

0
votes

Désolé, les autres réponses n'étaient pas applicables. Dans ce cas particulier, la réponse était d'avoir

IReturn<T> ... where T : FeatureBase

et d'avoir des instances étendant FeatureBase.


0 commentaires