检查通用接口

时间:2017-11-08 16:16:46

标签: c# generics interface subclass superclass

我有一个如下界面:

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(),但我想了解如何正确完成这一点,以及为什么我的方法不起作用。

1 个答案:

答案 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; }
    }