2016-03-29 4 views
0

Scénario estSur covariance et contravariance

public interface IRow 
{ 
    int Id { get; set; } 
    string Name { get; set; } 
} 
public class ARow : IRow 
{ ... } 
public class BRow : IRow 
{ ... } 
public class RowCollection<T> : Collection<T> where T : IRow 
{ } 

public interface ITable<T> where T : IRow 
{ 
    RowCollection<T> DataRows { get; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

public class ATable : ITable<ARow> 
{ 
    public RowCollection<ARow> DataRows 
    { 
     get; 
     set; 
    } 
} 

public class BTable : ITable<BRow> 
{ 
    public RowCollection<BRow> DataRows 
    { 
     get; 
     set; 
    } 
} 

Quand je fais quelque chose comme ça

 List<ITable<IRow>> lt = new List<ITable<IRow>>(); 
     ITable<IRow> ads = new ATable(); 

je suis erreur, je sais que quelque chose à voir avec covariance et contravariance si quelqu'un peut me aider à surmonter cette erreur sera très appréciée. Il est certain que j'ai besoin d'en savoir plus sur ce sujet, mais je m'attends à une aide rapide pour corriger ce problème/scénario en premier.

Cordialement, San

+0

également porté: [Comprendre Covariance et Contravariance en C# 4.0] (http://stackoverflow.com/questions/1724919/understanding-covariance-and-contravariance-in-c-sharp-4-0), [Comprendre les interfaces covariantes et contravariantes en C#] (http://stackoverflow.com/questions/2719954/understanding-covariant-and-contravariant-interfaces-in-c-sharp), [Pourquoi ne puis-je pas affecter une liste à une liste ?] (http://stackoverflow.com/questions/4652858/why-cant-i-assign-a-listderived-to-a-listbase); et il y en a beaucoup d'autres. – poke

+0

Si vous connaissez déjà le terme de ce qui vous cause des problèmes (covariance et contravariance), alors montrez quelques efforts et regardez les nombreuses questions * existantes * qui auraient dû vous être suggérées lorsque vous avez commencé à écrire cette question, et montrez que votre problème est en effet basé sur les connaissances que vous avez déjà acquises à l'aide de ces questions. – poke

+0

lire ma question complètement ... j'ai reconnu que c'est sur la variance co et la contravariance. Aussi mentionné que je suis à la recherche d'une aide rapide/solution et en apprendra plus sur ce sujet. – sanoj

Répondre

0

ATable est un ITable<ARow>; ce n'est PAS un ITable<IRow>. Si étaient, vous pouvez ajouter n'importe quel type de ligne qui implémente IRow, mais il ne peut prendre que les types de ligne qui héritent de ARow.

Si ITable étaient covariant (si elle était définie comme ITable<out T> alors vous pouvez traiter un ITable<ARow> comme ITable<IRow>, mais le mot-clé out indique que T est utilisé uniquement comme sorties des propriétés et méthodes. Depuis vous avez une propriété RowCollection<T> qui ne sont pas covariantes (car il hérite de Collection<T> qui utilise T comme entrées), vous ne pouvez pas ITable covariant.

Même si la propriété DataRows possède uniquement un accesseur get, cela ne fait que rendre la référence à la collection en lecture seule. Vous pouvez toujours ajouter T à la collection afin qu'elle ne soit pas covariante. Vous pouvez remplacer le type déclaré par IEnumerable<T> pour rendre la collection "en lecture seule" du point de vue de l'interface.

public interface ITable<out T> where T : IRow 
{ 
    IEnumerable<T> DataRows { get; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 
+0

Merci Stanley. Je m'attends à une collection en lecture seule (get) donc j'ai changé le code en conséquence. Merci pour vos points. – sanoj