Справочная информация:
У меня есть три страницы Silverlight, которые реализуют мой интерфейс:
interface IPageWithData<in T> where T : Entity
{
void SetData(T obj);
}
public class APage : Page, IPageWithData<AItem> { /* Implementation */ }
public class BPage : Page, IPageWithData<BItem> { /* Implementation */ }
public class CPage : Page, IPageWithData<CItem> { /* Implementation */ }
// AItem, BItem and CItem are (EF) Entities (they are derived from Entity class).
Затем я использую собственный менеджер, который возвращает страницу, которая относится к узлу древовидной структуры, заданному в качестве параметра:
private static class PageContainerHelper
{
public static IPageWithData<Entity> SetPage(RadTreeViewItem selectedNode)
{
APageRTVI aNode = selectedNode as APageRTVI;
BPageRTVI bNode = selectedNode as BPageRTVI;
CPageRTVI cNode = selectedNode as CPageRTVI;
if (aNode != null)
{
if (APage == null)
APage = new APage();
APage.SetData(aNode.aItem);
return APage; // ERROR HERE
}
/*
... the same for BPageRTVI and CPageRTVI
*/
}
public static APage APage { get; set; }
public static BPage BPage { get; set; }
public static CPage CPage { get; set; }
}
Проблема:
Кажется, я неправильно понимаю со / контрвариантность.
Метод SetPage()
не позволяет мне вернуть APage
:
Невозможно неявно преобразовать тип 'MyProject.Views.Pages.APage' в 'MyProject.Views.Pages.IPageWithData' . Существует явное преобразование (вам не хватает приведения?)
APage
реализует IPageWithData<T>
(хотя T
имеет более производный тип). Почему это требует явного преобразования? И будет ли здесь работать явное преобразование?
Так что, в принципе, мне нужны две вещи. Во-первых, когда SetPage
возвращает страницу, он может использовать страницу, которая реализует IPageWithData
типа, который является более производным, чем Entity
. И еще мне нужно, чтобы метод IPageWithData<T>.SetData
мог получать аргументы более производного типа, чем T
, то есть Entity
.
Возможно ли это?