检查通用接口上的约束

Check constraint on generic interface

我的界面如下:

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 语句失败了,如果我删除它,转换就会失败 (returns null)。我假设是因为 Target 没有具体实现 IHasDetailPage<ViewModelBase>,但是 IHasDetailPage<SpecificViewModel>,甚至很难实现 SpecificViewModel : ViewModelBase

如何执行此类型检查并正确转换?真的,我只需要能够调用 GetViewModel(),但我想了解如何正确完成此操作,以及为什么我的方法不起作用。

如果您可以控制接口,则可以使其协变。以下测试通过...

    [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; }
    }