VB.NET中Enum.GetValues重载的返回类型及调用版本判定
问题相关代码
Module Module1 Enum Colors Red Green Blue Yellow End Enum Sub main() Dim values = [Enum].GetValues(GetType(Colors)) ' 语句1 Console.WriteLine(values.GetType) '运行输出: Colors[] Console.ReadLine() End Sub End Module
问题描述
上述代码运行后输出显示values的运行时类型为Colors[]。已知Enum.GetValues存在两个不同的重载版本:
- 非泛型基础版:方法签名返回值为
Array类型,是泛型特性正式推出前就存在的旧版实现 - 泛型重载版:方法签名返回值为
TEnum[]类型
提问者最初作出如下推断:由于values的实际类型不是基类Array,而是具体的枚举数组类型Colors[],因此语句1调用的是返回TEnum[]的泛型重载版本。
具体待解答疑问如下:
- 上述推断是否正确?
- 若推断有误,请给出调用返回
TEnum[]类型的GetValues泛型重载的正确代码示例。 - 另有用户提出观点:返回
Array类型的GetValues是泛型特性推出前的旧版非泛型方法,语句GetValues(GetType(Colors))调用的并非该旧版本,该认知是否正确?
解答
- 原推断错误。
你观察到的values.GetType()返回Colors[]是运行时的实际对象类型,不能作为判断调用了泛型重载的依据:非泛型版本的GetValues虽然编译时静态返回类型标注为Array,但从.NET最早版本开始,这个方法运行时返回的实际对象本来就是对应枚举类型的强类型数组,这是旧版本本身就有的实现逻辑,不是泛型重载独有的特征。 - 泛型重载的正确调用方式不需要传入
Type类型参数,直接通过泛型参数指定枚举类型即可,VB环境下的写法如下:
对比原代码中的' 该写法才会匹配泛型重载,编译时values的静态类型直接为Colors(),无需额外类型转换 Dim values = [Enum].GetValues(Of Colors)()[Enum].GetValues(GetType(Colors))写法:由于传入了Type类型的实参,编译器会匹配到签名为GetValues(Type enumType)的非泛型旧重载,此时编译时values的静态类型为Array,直接访问数组成员时无法获得强类型智能提示,需要手动强转成Colors()才能按强类型枚举使用。 - 提到“传入Type参数的写法调用的不是旧版非泛型方法”的认知错误。
传入Type参数的调用,匹配的就是最早存在的非泛型旧版本。泛型重载是.NET Framework 4.5、.NET Core 1.0之后才新增的API,设计目的就是省去手动将返回的Array强转为对应枚举数组的步骤,让开发者在编译阶段就能拿到强类型的数组结果。
这里要特别注意区分编译时静态类型和运行时对象类型的差异:调用非泛型重载时,仅在运行时能检测到返回值是强类型枚举数组,编译阶段IDE只会将其识别为Array;调用泛型重载时,编译阶段IDE就能直接识别返回值为对应枚举的数组类型。
内容的提问来源于stack exchange,提问作者Sougata
相关产品推荐
相关产品推荐

