0

Scenario is

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;
    }
 }

When i do something like this

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

I get error, i know its something to do with covariance and contravariance if someone can help me overcome this error will be much appreciated.

For sure i need to learn more on this topic but expecting a quick help on fixing this issue/scenario first.

Regards, San

sanoj
  • 1
  • 1
  • Also related: [Understanding Covariance and Contravariance in C# 4.0](http://stackoverflow.com/questions/1724919/understanding-covariance-and-contravariance-in-c-sharp-4-0), [Understanding Covariant and Contravariant interfaces in C#](http://stackoverflow.com/questions/2719954/understanding-covariant-and-contravariant-interfaces-in-c-sharp), [Why can't I assign a List to a List?](http://stackoverflow.com/questions/4652858/why-cant-i-assign-a-listderived-to-a-listbase); and there are a bunch of others. – poke Mar 29 '16 at 18:42
  • If you already know the term of what is causing you problems (covariance and contravariance), then please show some effort and actually look at the many *existing* questions that should have been suggested to you when you started to write this question, and show that your problem is indeed based on the knowledge you already acquired with the help of those questions. – poke Mar 29 '16 at 18:43
  • read out my question completely... i have acknowledged that its on co variance and contravariance. Also mentioned that i am looking for a quick help/solution and will learn more on this topic. – sanoj Mar 29 '16 at 18:48
  • Well then please know that this is not a “fix my code” or “do my work for me” site. You are [expected to](http://stackoverflow.com/help/how-to-ask) invest work when you ask a question. And that includes actually bothering to try to solve the problem yourself first. – poke Mar 29 '16 at 18:57

1 Answers1

0

ATable is an ITable<ARow>; it is NOT an ITable<IRow>. If it were, you could add any row type that implements IRow, but it can only take row types that inherit from ARow.

If ITable were covariant (i.e. if it were defined as ITable<out T> then you could treat an ITable<ARow> as an ITable<IRow>, but the out keyword indicates that T is only used as outputs from properties and methods. Since you have a RowCollection<T> property that is not covariant (because it inherits from Collection<T> which uses T as inputs), you cannot make ITable covariant.

Even though the DataRows property only has a get accessor, that only makes the reference to the collection read-only. You can still add Ts to the collection so it is not covariant. You could change the declared type to IEnumerable<T> to make the collection "read-only" from the interface's standpoint.

public interface ITable<out T> where T : IRow
{
    IEnumerable<T> DataRows { get; }
    int Id { get; set; }
    string Name { get; set; }
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Thanks Stanley. I expectation is a readonly collection (get) so i have changed the code accordingly. Thanks for your points. – sanoj Mar 29 '16 at 18:50