如何检查并转换泛型类型?泛型类型校验失败问题咨询
问题原因
C#中默认泛型类是不变量——即便ChildViewModel继承自BaseViewModel,Base<ChildViewModel>与Base<BaseViewModel>之间也不存在继承关系,因此displayPage is Base<BaseViewModel>会返回false,无法通过类型检查调用Method。
解决方案
方案1:提取方法到非泛型基类
创建一个不带泛型参数的基类,将Method放在这个基类中,让泛型Base<T>继承它:
using System; public class Page{} public class ContentPage: Page{} public class BaseViewModel{} public class ChildViewModel : BaseViewModel {} // 新增非泛型基类,存放通用方法 public class BasePage : ContentPage { public void Method() { Console.WriteLine("in Base=>Method"); } } public class Base<T> : BasePage where T : BaseViewModel{} public class ChildPage : Base<ChildViewModel> {} public class Program{ public static void Main(){ Page displayPage = new ChildPage(); if(displayPage is BasePage basePage) { basePage.Method(); } } }
方案2:利用协变接口
定义一个带out关键字的协变接口(协变仅支持接口/委托,且类型参数只能用于输出位置),让泛型类实现该接口:
using System; public class Page{} public class ContentPage: Page{} public class BaseViewModel{} public class ChildViewModel : BaseViewModel {} // 协变接口,out标记T为协变类型 public interface IBase<out T> where T : BaseViewModel { void Method(); } public class Base<T> : ContentPage, IBase<T> where T:BaseViewModel{ public void Method(){ Console.WriteLine("in Base=>Method"); } } public class ChildPage : Base<ChildViewModel> {} public class Program{ public static void Main(){ Page displayPage = new ChildPage(); if(displayPage is IBase<BaseViewModel> basePage) { basePage.Method(); } } }
方案3:直接匹配具体子类
如果场景中具体子类数量有限,可以直接判断目标类型:
using System; public class Page{} public class ContentPage: Page{} public class BaseViewModel{} public class ChildViewModel : BaseViewModel {} public class Base<T> : ContentPage where T:BaseViewModel{ public void Method(){ Console.WriteLine("in Base=>Method"); } } public class ChildPage : Base<ChildViewModel> {} public class Program{ public static void Main(){ Page displayPage = new ChildPage(); if(displayPage is ChildPage childPage) { childPage.Method(); } } }
内容的提问来源于stack exchange,提问作者Sivagnanam Subramani
相关产品推荐
相关产品推荐

