也许我很蠢但是......
我有:
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>
我有点理解为什么错,但不完全!
答案 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上有一个非常详细,非常明确的问题解释(分成很多部分)。