开发者

C# interface as parameter type conversion problem

开发者 https://www.devze.com 2023-03-12 10:43 出处:网络
I have this method... public static IList<IOutgoingMessage> CompressMessages(IList<IOutgoingMessageWithUserAndPtMedInfo> msgs)

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>());
0

精彩评论

暂无评论...
验证码 换一张
取 消