J'essaie d'obtenir quelque chose de travail et de lutte avec ce qui suit en utilisant Contravariance. Ma compréhension est Covariance est où vous pouvez retourner un type dérivé d'un type de base. La contravariance est l'endroit où vous pouvez passer un type dérivé d'un type de base en tant qu'argument dans une classe.C# .net 4.0 Covariant vs Contravariante
J'ai donc l'interface ci-dessous (contravariant):
public interface IBase<in T> where T: BaseModel
{
void Process(T model);
}
J'ai alors une classe abstraite
public abstract class Base<T>: IBase<T> where T: BaseModel
{
public virtual void Process(T model)
{
// throw new System.NotImplementedException();
}
}
et une autre classe concrète
public class Parent: Base<ParentModel>
{
public override void Process(ParentModel model)
{
// throw new System.NotImplementedException();
}
}
Considérant le type générique est seulement jamais utilisé comme une entrée et non un type de retour, je ne vois pas pourquoi je ne peux pas faire ce qui suit:
IBase<BaseModel> baseContravariant = new Parent();
// This doesn't compile. I will eventually have a list of IBase<BaseMode> to which I'd like to pass in different parent instances.
J'ai un autre exemple utilisant covariance qui est ci-dessous et fonctionne bien.
public interface IBase<out T> where T : BaseModel, new()
{
T ProcessAndGet();
}
Résumé
public abstract class Base<T>: IBase<T> where T: BaseModel, new()
{
public virtual T ProcessAndGet()
{
var result = new T() as BaseModel;
// More shizzle here
return (T)result;
}
}
Béton
public class Parent : Base<ParentModel>
{
public override ParentModel ProcessAndGet()
{
var x = base.ProcessAndGet();
return x;
}
}
Maintenant, je peux faire
IBase<BaseModel> baseInstance = new Base<BaseModel>();
IBase<BaseModel> derived = new Parent();
baseInstance = derived;
Il y a plus de code pour les exemples ci-dessus, mais je l'ai enlevé pour faciliter lire (heureusement!) :-)
Merci pour la réponse et la réponse informative. Le deuxième exemple que j'ai fourni fait la même chose en termes d'étapes. La classe Parent ne prend que ParentModel mais je peux toujours l'assigner à la classe de base? Je pensais que c'était l'intention derrière la fonctionnalité in/out ... – tones
J'ai ajouté un paragraphe sur le type de covariant.Je ne suis pas tout à fait sûr de ce que votre vraie question pour être honnête .. (autre que de l'expliquer en termes plus faciles, tout remplacer par "producteur" et "consommateur" m'a toujours aidé à comprendre ce truc) –
Aah qui a du sens . Il n'y avait pas de question sur le second point. C'était comme si vous en disiez plus pour comparer les deux pour comprendre comme on a travaillé et l'autre pas. En bref pour la covariance, vous pouvez attribuer à des types moins spécifiques, mais la contravariance vous ne pouvez pas. J'espère avoir compris cela correctement. – tones