C#泛型类型判断语法疑问:如何用is检查myList<>类型?
问题分析与解决方案
你遇到的问题是C#中对非具体化泛型类型(也就是myList<>这种未指定类型参数的泛型)的类型检查和成员访问限制。C#不允许直接用is myList<>做类型判断,也不能直接将对象强制转换为非具体化泛型类型来访问成员,下面给你几种可行的解决办法:
方法1:使用泛型模式匹配(C# 7.0+推荐)
C# 7.0及以上支持泛型模式匹配,可以用is myList<var>(或显式写is myList<T>)捕获任意具体化的myList<T>实例,直接访问成员:
public class myList<T> where T : struct { public int number { get; set; } } public class TypeTest { public static int GetNumber(object x) { // 用模式匹配捕获任意myList<T>实例到list变量 if (x is myList<var> list) { return list.number; // 注意你原代码里写的`numb`是笔误哦 } return 0; } }
这里的var是无约束的类型参数,编译器会自动推断x实际对应的泛型类型参数,类型安全且代码简洁。
方法2:通过反射判断并访问成员(适用于旧版本C#)
如果你的项目基于C# 7.0之前的版本,可以通过反射检查类型是否是myList<>的具体化泛型,再获取属性值:
public class myList<T> where T : struct { public int number { get; set; } } public class TypeTest { public static int GetNumber(object x) { Type objType = x.GetType(); // 检查是否是泛型类型,且泛型定义是myList<> if (objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(myList<>)) { // 反射获取number属性的值 int result = (int)objType.GetProperty(nameof(myList<int>.number)).GetValue(x); return result; } return 0; } }
这种方法不需要修改原myList<T>的定义,但反射会有一定性能开销,适合偶尔使用的场景。
方法3:添加非泛型接口(最优雅的类型安全方案)
如果可以修改myList<T>的定义,建议给它实现一个非泛型接口,这样就能直接通过接口类型做类型判断和成员访问,完全避免泛型类型的困扰:
// 定义非泛型接口 public interface IMyList { int number { get; set; } } // 让myList<T>实现接口 public class myList<T> : IMyList where T : struct { public int number { get; set; } } public class TypeTest { public static int GetNumber(object x) { // 直接判断是否是IMyList类型 if (x is IMyList list) { return list.number; } return 0; } }
这种方案类型安全、性能最优,也是C#中处理泛型类型多态的常规做法。
内容的提问来源于stack exchange,提问作者Impostor
相关产品推荐
相关产品推荐

