views:

81

answers:

2

I have one generic interface in c#, and almost always I use it with one of the types. I want to create a non-generic interface for that type and use it.

Let's say, I've the following code:

public interface IMyGenericList<out T> where T : IItem
{
    IEnumerable<T> GetList();
}

public class MyList<T> : IMyGenericList<T> where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }
}

it works well. Most times I need IMyGenericList<IItem>, so i try the following:

public interface IMyItemsList : IMyGenericList<IItem>
{
}

but I can't make MyList implement IMyItemsList for some reason. The following code returns an error

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }
}

saying that IEnumerable<IItem> is not implemented.

Why is it so/what can I do with this? Thanks.

Ok, thanks to your answers I figured out it's impossible to do it exactly as I wanted initially. I will post another question on why this is impossible :) Here it is: http://stackoverflow.com/questions/4049702/one-function-implementing-generic-and-non-generic-interface

+1  A: 

You cannot have your IMyItemsList interface inherited from IMyGenericList<out T> interface if you want to have MyList<T> implementing both of them. But you can modify your IMyItemsList interface as defined below:

public interface IItem
{
}

public interface IMyItemsList
{
    IEnumerable<IItem> GetList();
}

public interface IMyGenericList<out T> where T : IItem
{
    IEnumerable<T> GetList();
}

public class MyList<T> : IMyGenericList<T>, IMyItemsList 
    where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }

    IEnumerable<IItem> IMyItemsList.GetList()
    {
        return this.GetList().Cast<IItem>();
    }
}
Andrew Bezzub
+1  A: 

You specific example wouldn't work, as your class:

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem
{
  public IEnumerable<T> GetList()
  {
    return null;
  }
}

is trying to implement both a IEnumerable<IItem> GetList() and an IEnumerable<T> GetList(), which are two different things. This first is explicitly an enumerable of IItem (as required by your IMyItemsList interface), and the second is an enumerable of T.

In this scenario T is of type IItem but is not explicitly IItem. Therefore at compile time, the IEnumerable<IItem> GetList() is not IEnumerable<T> GetList() so the compiler will correctly throw an error telling you that IEnumerable<IItem> GetList() is not implemented.

The other problem you will run into, is what happens when somebody does:

var list = new MyList<IItem>();

The compiler will try and create an a concrete implementation of MyList<IItem> which will have two definitions of IEnumerable<IItem> GetList().

I would reconsider your design to evaluate a singular IEnumerable<T> GetList().

Also, and just picky on my part: "enumerable" != "list" :P

Matthew Abbott
imho, IEnumerable<T> where T : IItem can be always casted to IEnumerable<IItem>, isn't it? I thought, it's what covariance is for in .net? I agree with you, that it looks ugly and will cause problems to have a separate explicit IEnumerable<IItem> GetList() implementation
Shaddix