J'ai une classe de base: et une classe qui stocke les références code> DomainEventsSUCCREDER p> Même si le type de méthode code> code> est contraint, je ne peux pas convertir de Domaineventsubscriber où T: DomainEvent code> à DomaineVentsUscriber Code>: P> eventSubscriber = (DomainEventSubscriber<DomainEvent>)subscriber;
3 Réponses :
Vous avez besoin d'une interface avec un paramètre de type covariant Cependant, vous ne pouvez pas faire Note le mot clé code> dans code>, ce qui signifie Mais cela ne résout également pas votre problème car vous ne pouvez pas lancer un paramètre de type Contravariant uniquement sur un type dérivé plus em> et que vous souhaitez la jeter au type de base. P> Je vous conseille de créer une interface code> non générique code> et dérivez votre classe actuelle à partir de celle: P> t code> pour pouvoir le jeter à un type de base de t code>. Par exemple, ienumerable out code>, ce qui signifie t code> est covariant et peut donc uniquement apparaître dans les positions sortie em> (par exemple, valeurs de retour et getters). À cause de la covariance, vous pouvez lancer un iEnumerable ienumerable Contravariance h3>
Domaineventsubscriber IdomainevationsSUCCRITER t code> t code> Apparaît ensuite dans la position em> entrée em> de gureVent code>. Vous pouvez en faire une interface idomainevientsubscriber t code> est Contravariant em> et peut seulement apparaître dans les positions Entrée em> (par exemple, comme paramètres de la méthode). Par exemple, IequalityComparer IequalityComparer IéqualityComparer
Solution h3>
public class DomainEventPublisher
{
private List<IDomainEventSubscriber> subscribers;
public void Subscribe<T>(DomainEventSubscriber<T> subscriber)
where T : DomainEvent
{
if (!this.Publishing)
{
this.subscribers.Add(eventSubscriber);
}
}
}
Voici une prise légèrement différente à l'aide d'une interface:
public class DomainEvent
{
}
// The 'in' isn't actually needed to make this work, but it can be added anyway:
public interface IDomainEventSubscriber<in T> where T: DomainEvent
{
void HandleEvent(T domainEvent);
Type SubscribedToEventType();
}
public abstract class DomainEventSubscriber<T>: IDomainEventSubscriber<T> where T: DomainEvent
{
public abstract void HandleEvent(T domainEvent);
public Type SubscribedToEventType()
{
return typeof(T);
}
}
public class DomainEventPublisher
{
private List<DomainEventSubscriber<DomainEvent>> subscribers;
public void Subscribe<T>(IDomainEventSubscriber<T> subscriber)
where T: DomainEvent
{
DomainEventSubscriber<DomainEvent> eventSubscriber;
eventSubscriber = (DomainEventSubscriber<DomainEvent>)subscriber;
if (!this.Publishing)
{
this.subscribers.Add(eventSubscriber);
}
}
}
Il y a de bonnes réponses pour la solution, ici, je sors un peu pour la simple raison pour laquelle vous ne pouvez pas le faire fonctionner.
Les classes de base génériques peuvent être héritées, cependant, avec différents paramètres de type ne sont que des classes différentes. Considérons Ceci ne compilerait pas, et même que vous modifiez la déclaration de compilée, comme: P> Liste list list`1 code>, mais ils prennent différents paramètres de type; Aucun d'entre eux n'est la classe de base de l'autre. Quelle est votre méthode, serait comme suit: p> public void Subscribe<T>(List<T> subscriber) where T: struct {
var eventSubscriber=(List<int>)(subscriber as object);
// ...
}
Vous avez besoin d'une interface avec une valeur. Je ne sais pas si vous pouvez le faire ici.
Néanmoins, il vaut la peine de coller un
out code> dansDomainevomSubscriber Où T: DomaineEvent code> Pour voir si cela fonctionne. @Matthewwatson qui sera jamais i> travail depuis
out code> etdans code> Les modificateurs de type générique ne peuvent être utilisés que avec des interfaces, pas des classes i> .@VirtLink Fair assez, peut-être qu'il pourrait essayer de faire une interface!
Votre conception est défectueux. Vous essayez de vous donner la capacité de pouvoir envoyer une instance Simple
DomainEvent CODE> àGUESSEvent (MydomainEvent) CODE> Méthode, qui ne fonctionnera jamais. Le compilateur a fait du bon travail en vous protégeant de cela.