C#泛型接口is类型判断条件始终返回false问题排查
问题原因
你遇到的类型判断始终为false的问题由两个核心原因导致:
- 泛型类型默认不变性:C#中未声明协变/逆变的泛型接口,其不同泛型参数构造的类型之间不存在继承兼容关系。你定义的
IHasKlarfImageList<TImageListInfo>没有添加协变修饰符,即使CIMKlarfImageListInfo、RMTKlarfImageListInfo都实现了IKlarfImageListInfo接口,IHasKlarfImageList<CIMKlarfImageListInfo>、IHasKlarfImageList<RMTKlarfImageListInfo>也不会被识别为IHasKlarfImageList<IKlarfImageListInfo>的子类型,is判断自然永远返回false。 - 接口实现与参数类型不匹配:你贴出的
CIMKlarfDefect、RMTKlarfDefect两个类,都只实现了非泛型版IKlarfDefect,没有实现泛型版IKlarfDefect<TImageListInfo>,本身无法作为IEnumerable<IKlarfDefect<IKlarfImageListInfo>>的元素传入函数。另外RMTKlarfDefect的声明存在笔误:类声明写的是实现IHasKlarfImageList<CIMKlarfImageListInfo>,但实际属性类型是List<RMTKlarfImageListInfo>,这段代码本身无法通过编译。
修复方案
- 修正类的接口实现
两个缺陷类需要正确实现对应泛型接口,修正笔误,保证泛型参数一致:// 假设CIMKlarfImageListInfo、RMTKlarfImageListInfo均实现IKlarfImageListInfo接口 public class CIMKlarfDefect : IKlarfDefect<CIMKlarfImageListInfo>, IHasKlarfImageList<CIMKlarfImageListInfo> { public int TEST { get; set; } public int DEFECTID { get; set; } public List<CIMKlarfImageListInfo> KlarfImageList { get; set; } = new(); } public class RMTKlarfDefect : IKlarfDefect<RMTKlarfImageListInfo>, IHasKlarfImageList<RMTKlarfImageListInfo> { public int TEST { get; set; } public int DEFECTID { get; set; } public List<RMTKlarfImageListInfo> KlarfImageList { get; set; } = new(); } - 为支持协变的泛型接口添加
out修饰符
协变要求泛型参数只能出现在接口成员的返回值位置,你的IHasKlarfImageList<T>中KlarfImageList是只读属性,符合协变要求。注意List<T>本身是支持读写的不变类型,要实现安全协变需要将属性类型改为IReadOnlyList<T>:
注意// 添加out修饰符声明协变后,构造的子类型泛型接口可隐式转换为父类型泛型接口 public interface IHasKlarfImageList<out TImageListInfo> { IReadOnlyList<TImageListInfo> KlarfImageList { get; } }IKlarfDefect<T>中的KlarfImageList存在setter,泛型参数出现在入参位置,无法声明协变。 - 调整函数参数类型
由于IKlarfDefect<T>无法声明协变,你不能用IEnumerable<IKlarfDefect<IKlarfImageListInfo>>作为参数接收两种不同泛型实现的缺陷类,将参数改为非泛型的IEnumerable<IKlarfDefect>即可:internal static string CreateCIMDefectListString(IEnumerable<IKlarfDefect> klarfDefectList) { StringBuilder defectListString = new StringBuilder(); defectListString.AppendLine(""); foreach (var klarfDefect in klarfDefectList) { defectListString.Append(klarfDefect.TEST).Append(" "); defectListString.Append(klarfDefect.DEFECTID).Append(" "); if (klarfDefect is IHasKlarfImageList<IKlarfImageListInfo> grcKlarfDefect) { if (grcKlarfDefect.KlarfImageList.Count == 0) { defectListString.Append("N;"); defectListString.AppendLine(); } } } return defectListString.ToString(); }
内容的提问来源于stack exchange,提问作者devn00b1090
相关产品推荐
相关产品推荐

