Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface with a list of Interfaces

Maybe I'm dumb but ...

I have:

public interface IRequest
{
    IList<IRequestDetail> Details { get; set; }

    // stuff
}

public interface IRequestDetail
{
    // stuff
}

I then have:

public class MyRequest : IRequest
{
    IList<MyRequestDetail> Details {get; set; }

    // stuff
}

public class MyRequestDetail : IRequestDetail
{
    // stuff
}

It doesn't work.

C# gets pissed at me because MyRequest does not implement the interface due to not having an IList of IRequestDetail.

Now if I change it so the Details is IList of IRequestDetail I then have to cast it to MyRequestDetail everywhere in the code I use a non-interface member (I have several requests that share common stuff, but then specialize).

I kind of understand why its wrong, but not fully!

like image 982
anonymous Avatar asked Dec 01 '22 07:12

anonymous


1 Answers

I think, based on the question that the problem is that you want to treat Details as a generic list and enforce that it implements IRequestDetail. You also want it to be more specifically typed for the implementing classes. In this case, you need to make IRequest generic.

Try this:

public interface IRequest<T> where T : IRequestDetail
{
    IList<T> Details { get; set; }

    // stuff
}

public class MyRequest : IRequest<MyRequestDetail>
{
    public IList<MyRequestDetail> Details {get; set; }

    // stuff
}

This should work for you.

EDIT 2017-03-17

In reply to @Robert's comment, see the expanded code below:

public interface IRequestDetail
{

}

public class MyRequestDetail : IRequestDetail
{

}

public interface IRequest<T> where T : IRequestDetail
{
    IList<T> Details { get; set; }

    // stuff
}

public class MyRequest<T> : IRequest<T>
    where T : IRequestDetail
{
    public IList<T> Details { get; set; }

    // stuff
}

public class Consumer
{
    public void MyFunction<T>(IRequest<T> request)
        where T : IRequestDetail
    {

    }

    public void Foo()
    {
        var test = new MyRequest<MyRequestDetail>();
        MyFunction(test);
    }
}
like image 141
Michael Meadows Avatar answered Dec 04 '22 15:12

Michael Meadows