C# interface as parameter type conversion problem
I have this method...
public static IList<IOutgoingMessage> CompressMessages(IList<IOutgoingMessageWithUserAndPtMedInfo> msgs)
{
StoreOriginalMessages(msgs);
...
}
which calls into this method...
private static void StoreOriginalMessages(IList<IOutgoingMessage> msgs) {...}
and IOutgoingMessageWithUserAndPtMedInfo
is defined like this...
public interface IOutgoingMessageWithUserAndPtMedInfo: IOutgoingMessage
{
IPatientMedication PatientMedication { get; set; }
IUserContainer User{ get; set; }
}
I getting this error when I try to call StoreOriginalMessages
from my CompressMessages
开发者_JS百科method:
cannot convert from 'System.Collections.Generic.IList<MyMediHealth.DataAccess.Containers.IOutgoingMessageWithUserAndPtMedInfo>
' to 'System.Collections.Generic.IList<MyMediHealth.DataAccess.Containers.IOutgoingMessage>
'
Don't understand why. I would expect that it would accept it because IOutgoingMessageWithUserAndPtMedInfo
inherits from IOutgoingMessage
.
What am I doing wrong?
Reference: Covariance and Contravariance in Generics
Assuming the following 2 interfaces and 2 classes:
interface IBase {}
interface IDerived : IBase {}
class Base {}
class Derived : Base {}
If you do this, you'll get the same casting error:
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>
However, the following will compile just fine, because IEnumerable<T>
is declared for covariance, where IList<T>
is not. IEnumerable<T>
is actually IEnumerable<out T>
, denoting that the type parameter is for return values only, and can allow covariance.
IEnumerable<IDerived> lid = null;
IEnumerable<IBase> lib = lid;
IEnumerable<Derived> ld = null;
IEnumerable<Base> lb = ld;
From names of your methods I conclude that StoreOriginalMessages doesn't insert new elements in the list?
You could replace it by
private static void StoreOriginalMessages(IEnumerable<IOutgoingMessage> msgs)
And it should work smoothly (if you have C# 4.0 - before there was no covariance support unfortunately).
If you working with C# 3.5 you need to change call site as well:
StoreOriginalMessages(msgs.Cast<IOutgoingMessage>());
精彩评论