如何将两个类似的具体对象传递给具有在C#中实现泛型的接口参数的方法?

时间:2012-03-19 15:59:43

标签: c# generics interface

我有以下接口声明:

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>添加到原始接口声明中,但这增加了更多我无法解决的错误。这是我第一次深入涉及界面,我确信泛型增加了复杂性,因此这里可能存在根本缺乏理解。

2 个答案:

答案 0 :(得分:6)

你试过这个:

public static void UpdateDistro<T>(IDistro<T> distro) 
  where T : IOrderItem
{  
} 

编辑:

对于DistroItemPerishableItem类的空实现(都实现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),允许隐式转换实现变体接口的类。