不开启Option Strict On时如何实现VB对象属性严格类型校验
不开启全局Option Strict On实现VB.NET对象属性严格类型校验
问题背景
当Option Strict处于关闭状态(项目默认配置)时:
- 若属性为String类型,VB会自动调用传入值的
ToString()方法完成类型转换 - 对于可隐式转换的值类型(如Integer转Double),编译器会自动插入转换逻辑
需求为让指定属性遵循严格类型规则:赋值时传入的类型必须与属性声明类型完全匹配,且不希望开启全局Option Strict On影响其他现有代码。
已排除的方案:使用DynamicObject自定义属性赋值逻辑,该方案需要放弃类的显式属性定义,会破坏编辑器自动补全能力,不满足需求。
问题复现
测试代码如下:
Option Strict Off Class TestObj Private _foo As String Public Property Foo as String Get Return _foo End Get Set(v As String) Console.Write(String.Format("v = <{0}> {1}", v.GetType().FullName, v)) _foo = v End Set End Property End Class Dim o as New TestObj() o.Foo = "some_str" o.Foo = 1234 o.Foo = DateTime.Now()
运行时所有传入值在进入setter前就已经被自动转换为String类型,输出如下:
v = <System.String> some_str v = <System.String> 1234 v = <System.String> 7/7/2022 8:22:49 PM
注意:该隐式转换是编译器在编译阶段直接在赋值调用处插入的转换代码,执行顺序早于属性setter逻辑,因此在强类型声明的setter内部无法获取原始传入的非目标类型值。
可行方案
方案1:按文件粒度开启Option Strict On(推荐)
VB.NET支持文件级别的编译选项配置,无需全局开启Option Strict On:
仅需要在需要严格类型校验的类文件最顶部,单独添加Option Strict On声明即可,该配置仅对当前文件内的代码生效,完全不会影响项目中其他保持Option Strict Off的文件逻辑。
该方案下所有类的属性、方法依然可以保持显式强类型定义,编辑器的自动补全、类型检查能力完全不受影响,是成本最低、体验最好的实现方式。
方案2:属性参数声明为Object手动校验(仅适用于单属性控制场景)
如果不希望整个文件开启严格检查,可以将需要校验的属性的setter参数类型改为Object,在setter内部手动做类型全等校验,拦截不符合要求的赋值:
Option Strict Off Class TestObj Private _foo As String ' 注意属性对外暴露类型为Object,会丢失部分类型提示 Public Property Foo As Object Get Return _foo End Get Set(v As Object) ' 校验类型必须完全匹配,不接受任何隐式转换 If v.GetType() IsNot GetType(String) Then Throw New InvalidCastException($"属性Foo仅支持String类型赋值,当前传入类型为{v.GetType().FullName}") End If Dim typedVal As String = DirectCast(v, String) Console.Write(String.Format("v = <{0}> {1}", typedVal.GetType().FullName, typedVal)) _foo = typedVal End Set End Property End Class
该方案的缺点是属性对外暴露的类型为Object,会丢失强类型的智能提示能力,仅适合无法按文件开启Option Strict On的特殊场景使用。
内容的提问来源于stack exchange,提问作者Timothy C. Quinn
相关产品推荐
相关产品推荐

