2011-06-13 81 views
1

我有这样的方法...C#接口作为参数类型转换问题

public static IList<IOutgoingMessage> CompressMessages(IList<IOutgoingMessageWithUserAndPtMedInfo> msgs) 
    { 
     StoreOriginalMessages(msgs); 
     ... 
    } 

它调用这个方法...

private static void StoreOriginalMessages(IList<IOutgoingMessage> msgs) {...} 

IOutgoingMessageWithUserAndPtMedInfo定义像这样...

public interface IOutgoingMessageWithUserAndPtMedInfo: IOutgoingMessage 
{ 
    IPatientMedication PatientMedication { get; set; } 
    IUserContainer User{ get; set; } 
} 

我在尝试从我的CompressMessages方法中调用StoreOriginalMessages方法时出现此错误:

不能转换从 'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessageWithUserAndPtMedInfo>' 到 'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessage>'

不明白为什么。我希望它会接受它,因为IOutgoingMessageWithUserAndPtMedInfo继承自IOutgoingMessage

我在做什么错?

回答

3

从您的方法的名称我得出结论StoreOriginalMessages不会在列表中插入新元素?

您可以通过

private static void StoreOriginalMessages(IEnumerable<IOutgoingMessage> msgs) 

更换它应该工作顺利进行(如果你有C#4.0 - 以前没有协支持不幸)。

如果你用C#3.5的工作,你需要改变通话的网站,以及:

StoreOriginalMessages(msgs.Cast<IOutgoingMessage>()); 
+0

我在3.5工作,所以标记为答案。谢谢! – Marvin 2011-06-14 15:15:29

5

参考:Covariance and Contravariance in Generics

假设下面的2个接口和2类:

interface IBase {} 
interface IDerived : IBase {} 

class Base {} 
class Derived : Base {} 

如果你这样做,你会得到同样的错误铸造:

IList<IDerived> lid = null; 
IList<IBase> lib = lid; //cannot cast IList<IDerived> to IList<IBase> 

IList<Derived> ld = null; 
IList<Base> lb = ld; //cannot cast IList<Derived> to IList<Base> 

然而,以下将编译得很好,因为IEnumerable<T>被声明为协方差,其中IList<T>不是。 IEnumerable<T>实际上是IEnumerable<out T>,表示类型参数仅用于返回值,并且可以允许协方差。

IEnumerable<IDerived> lid = null; 
IEnumerable<IBase> lib = lid; 

IEnumerable<Derived> ld = null; 
IEnumerable<Base> lb = ld; 
+0

这是100%正确的。 – msarchet 2011-06-14 00:05:46

+2

你绝对可以通过接口来做到这一点,问题是IList 在T中不是协变的。这是因为IList 公开了像Add这样的方法,这可能会在协变场景下破坏行为(将Tiger添加到正在使用的长颈鹿集合中作为哺乳动物的一个集合)。代替使用IEnumerable ,代码将正常工作。 – 2011-06-14 00:08:50

+0

@Chris:您的评论胜过我的编辑。我重复了我的答案。 – 2011-06-14 00:12:18