如何使用List(Of Type)中的元素指定变量类型?
在VB.NET中存储类类型到List并动态创建实例
当然可以实现这个需求!不过因为VB.NET是静态类型语言,你没法直接用变量作为类型来声明变量(比如Dim obj As targetType这种写法编译不过),但我们可以借助Type类型和反射来达成目标,下面一步步给你演示:
1. 先把类类型存入List
首先,我们需要用Type类型来表示类本身,然后把这些Type对象放进List(Of Type)里:
' 先定义你的三个类 Class a Public gI As String End Class Class b Public gI As String End Class Class c Public gI As String End Class ' 创建存储类类型的List Dim classTypes As New List(Of Type)() classTypes.Add(GetType(a)) ' 添加类a的类型 classTypes.Add(GetType(b)) ' 添加类b的类型 classTypes.Add(GetType(c)) ' 添加类c的类型
2. 从List中取出类型并创建实例
接下来,我们可以从List里拿到目标类型,用Activator.CreateInstance方法创建该类型的实例。这里要注意:你的类需要有无参构造函数(默认如果没写构造函数的话,VB会自动生成),否则需要传递构造参数给CreateInstance。
基础用法(用Object引用实例)
' 从List中取第一个类型(比如类a的Type) Dim targetType As Type = classTypes(0) ' 创建该类型的实例 Dim obj As Object = Activator.CreateInstance(targetType) ' 如果要访问gI字段,可以用反射 Dim giField As System.Reflection.FieldInfo = targetType.GetField("gI") giField.SetValue(obj, "我是类a的实例!") Console.WriteLine(giField.GetValue(obj)) ' 输出:我是类a的实例!
更优雅的方式:用共同接口/基类
如果你的类有共同的成员(比如都有gI),最好定义一个接口或者基类,这样就不用每次都用反射访问成员,类型更安全:
' 定义一个接口,包含共同的成员 Interface IHasGI Property GI As String End Interface ' 让你的类实现这个接口 Class a Implements IHasGI Public Property GI As String Implements IHasGI.GI End Class Class b Implements IHasGI Public Property GI As String Implements IHasGI.GI End Class Class c Implements IHasGI Public Property GI As String Implements IHasGI.GI End Class ' 之后创建实例时,可以直接转换为接口类型 Dim targetType As Type = classTypes(1) ' 取类b的类型 Dim obj As IHasGI = DirectCast(Activator.CreateInstance(targetType), IHasGI) obj.GI = "我是类b的实例!" Console.WriteLine(obj.GI) ' 输出:我是类b的实例!
3. 注意事项
- 如果你的类没有无参构造函数,需要用
Activator.CreateInstance(targetType, 参数1, 参数2)的形式传递构造参数。 - 反射操作的性能比直接创建实例稍差,如果是高频调用场景,可以考虑缓存构造函数的
MethodInfo来优化。 - 没法直接用变量作为类型声明(比如
Dim obj As targetType),因为VB.NET在编译时需要确定变量的类型,而targetType是运行时的变量。
内容的提问来源于stack exchange,提问作者Bigbob556677
相关产品推荐
相关产品推荐

