我有以下接口声明:
interface IOrder<T> where T: IOrderItem
{
IList<T> Items { get; set; }
}
interface IDistro<T> : IOrder<T> where T: IOrderItem
{
}
我有两个具体的课程,如下:
// DistroItem implements IOrderItem
public class Distro : IDistro<DistroItem>
{
public IList<DistroItem> Items { get; set; }
}
// PerishableOrderItem implements IOrderItem
public class PerishableOrder : IDistro<PerishableOrderItem>
{
public IList<PerishableOrderItem> Items { get; set; }
}
最后,我有一个用于保存到数据库的静态服务方法:
public static void UpdateDistro(IDistro<IOrderItem> distro)
{
}
我的问题是,如何将具体类型的发行版传递给我的静态方法?以下内容无法编译:
Distro d = new Distro();
UpdateDistro(d);
错误是:
The best overloaded method match for UpdateDistro(IDistro<IOrderItem>)' has some invalid arguments
逆变是答案吗?我尝试将<in T>
添加到原始接口声明中,但这增加了更多我无法解决的错误。这是我第一次深入涉及界面,我确信泛型增加了复杂性,因此这里可能存在根本缺乏理解。
答案 0 :(得分:6)
你试过这个:
public static void UpdateDistro<T>(IDistro<T> distro)
where T : IOrderItem
{
}
编辑:
对于DistroItem
和PerishableItem
类的空实现(都实现IOrderItem
),我进行了以下编译而没有错误:
Distro d = new Distro();
PerishableOrder p = new PerishableOrder();
UpdateDistro(d);
UpdateDistro(p);
答案 1 :(得分:0)
您可以在界面中定义协变通用参数,您需要稍微更改一下界面,以确保T
不会违反使用:
public interface IOrder<out T> where T : IOrderItem
{
IEnumerator<T> Items { get; }
}
public interface IDistro<out T> : IOrder<T> where T : IOrderItem
{
}
要将T
定义为覆盖参数(out
),允许隐式转换实现变体接口的类。