与接口列表的接口

时间:2009-04-30 16:09:42

标签: c# generics interface

也许我很蠢但是......

我有:

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

    // stuff
}

public interface IRequestDetail
{
    // stuff
}

然后我有:

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

    // stuff
}

public class MyRequestDetail : IRequestDetail
{
    // stuff
}

它不起作用。

C#对我很生气,因为MyRequest由于没有IRequestDetail的IList而没有实现接口。

现在,如果我更改它,那么详细信息是IRequestDetail的IList,那么我必须将它转换为MyRequestDetail代码中的任何地方我使用非接口成员(我有几个请求共享常见的东西,但然后专门化)。< / p>

我有点理解为什么错,但不完全!

3 个答案:

答案 0 :(得分:12)

我认为,基于问题是您希望将详细信息视为通用列表并强制实施IRequestDetail的问题。您还希望为实现类更具体地键入它。在这种情况下,您需要将IRequest设为通用。

试试这个:

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
}

这应该适合你。

编辑2017-03-17

在回复@ Robert的评论时,请参阅下面的扩展代码:

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

答案 1 :(得分:2)

精确。 迈克尔有解决方案。 问题有点棘手。

它没有明确的转换

IList<MyRequestDetail>

IList<IRequestDetail>

因为这意味着您可以添加其他对象,这些对象基于不同的类(例如MyRequestDetail2),而不是第二个对象的“MyRequestDetail”。 这对第一个来说是非法的。

答案 2 :(得分:0)

这是由于C#中的协方差和逆变。在Eric Lippert's Blog上有一个非常详细,非常明确的问题解释(分成很多部分)。