3

インターフェイスをパラメータとして受け入れるメソッドを呼び出す必要があります。パラメータとして使用しているオブジェクトはインターフェイスを実装していますが、それでもコンパイルエラーが発生します。私は何が間違っているのですか?

public class ViewModel 
{
    public ViewModel()
    {
        QueueManager<CFMessage<CFQueueItem>, CFQueueItem> q = new QueueManager<CFMessage<CFQueueItem>, CFQueueItem>();
        DoSomething(q);     // This line does not compile:  Cannot convert from QueueManager<CFQueueItem> to QueueManager<IQueueItem>
    }

    public void DoSomething(QueueManager<IQueueMessage<IQueueItem>, IQueueItem> queueManager)
    {

    }
}

public interface IQueueMessage<T> where T : IQueueItem
{
    int ID { get; set; }
}

public interface IQueueItem
{
    int ID { get; set; }
}

public class CFMessage<CFQueueItem> : IQueueMessage<CFQueueItem> where CFQueueItem : IQueueItem
{
    public int ID { get; set; }
}

public class CFQueueItem : IQueueItem
{
    public int ID { get; set; }
}

public class QueueManager<T, Q>
    where T : IQueueMessage<Q>
    where Q : IQueueItem
{

}
4

2 に答える 2

4

概念の共分散を使用して回避し、キーワードを使用してインターフェースIQueueMessage共分散outとして定義できます。

public interface IQueueMessage<out T> where T : IQueueItem
{
}

次に、次の新しい共変インターフェースIQueueManagerを作成しQueueManagerます。

public interface IQueueManager<out T, out Q> where T : IQueueMessage<Q>
                                             where Q : IQueueItem
{
}

public class QueueManager<T, Q> : IQueueManager<T, Q>
    where T : IQueueMessage<Q>
    where Q : IQueueItem
{

}

次に、このインターフェースをメソッドに使用できますDoSomething

public void DoSomething(IQueueManager<IQueueMessage<IQueueItem>, IQueueItem> queueManager)
{
}

コードは正常にコンパイルされます。

public ViewModel()
{
    var q = new QueueManager<CFMessage<CFQueueItem>, CFQueueItem>();
    DoSomething(q);
}
于 2012-10-13T18:21:35.463 に答える
3

メソッドをジェネリックにしてみてください。これは、インターフェースを共変にすることができない場合でも機能します。

public void DoSomething<TMessage, TItem>(QueueManager<TMessage, TItem> queueManager) 
    where TMessage : IQueueMessage<TItem>
    where TItem : IQueueItem
{ 
     //...
} 
于 2012-10-13T18:33:01.773 に答える