我有一个如下界面:
public interface IHasDetailPage<TViewModel> where TViewModel : ViewModelBase
{
TViewModel GetViewModel();
}
稍后在我的代码中,我有一个我知道实现此接口的对象。但是,在编译时,我确实知道它使用的特定类型参数。我想通过调用上面的函数来检索该对象的ViewModel:
ModelBase Target = DbHelper.Find(... // Retrieves this object from the database
if(Target is IHasDetailPage<ViewModelBase>)
{
ViewModel = (Target as IHasDetailPage<ViewModelBase>).GetViewModel();
}
同样,我知道Target
实现IHasDetailPage
,而ViewModel是ViewModelBase
的子类。但是这个if语句失败了,如果我删除它,则转换失败(返回null
)。我假设因为Target没有具体实现IHasDetailPage<ViewModelBase>
,而是IHasDetailPage<SpecificViewModel>
,甚至没有SpecificViewModel : ViewModelBase
。
如何正确执行此类型检查和投射?实际上,我所需要的只是能够致电GetViewModel()
,但我想了解如何正确完成这一点,以及为什么我的方法不起作用。
答案 0 :(得分:4)
如果您可以控制界面,则可以使其协变。以下测试通过......
[TestMethod]
public void DetailPage_ShouldBeOfFooType()
{
var target = new Target();
Assert.IsTrue(target is IHasDetailPage<Foo>);
}
public class Foo { }
public class Bar : Foo { }
public interface IHasDetailPage<out TViewModel> where TViewModel : Foo
{
TViewModel GetViewModel();
}
public class Target : IHasDetailPage<Bar>
{
public Bar GetViewModel() { return null; }
}