【问题标题】:Reflection and changing a variables type at runtime?在运行时反射和更改变量类型?
【发布时间】:2011-02-24 07:27:03
【问题描述】:

我正在尝试创建一个特定类型的对象。我有以下代码,但它失败了,因为它无法将新表对象转换为已定义的表对象。我需要以 IEnumerable 类型开头的表,所以我不能声明它是一个对象。

Public sub getTable(ByVal t as Type)

   Dim table As Table(Of Object)

   Dim tableType As Type = GetType(Table(Of )).MakeGenericType(t)

   table = FormatterServices.GetUninitializedObject(tableType)

End sub 

简而言之 - 有没有办法在运行时更改变量类型? (或者更好的方式来做我正在做的事情)

提前致谢。

詹姆斯

【问题讨论】:

    标签: vb.net reflection types


    【解决方案1】:

    在回答之前,我确实有两句话:

    • 我同意 Joel 的观点,即通用解决方案会简单得多,但如果没有更多上下文,我会假设您确实需要反思
    • 为什么要使用 FormatterServices.GetUninitializedObject()?这不会调用 Table 对象的构造函数。我猜你实际上是想在这里使用 Activator.CreateInstance()。

    现在,谈谈手头的问题。您遇到了 .Net 中缺乏对协方差(和逆变)的支持。赋值语句永远不会起作用,也没有反射:

    ' does not compile (with Option Strict On)
    Dim t as Table(Of Object) = New Table(Of Product)
    

    原因是类型实际上不同。虽然 Product 继承自 Object,但这并不意味着 Table(Of Product) 不继承自 Table(Of Object)。

    .Net 4 实际上确实支持泛型协变,但仅支持泛型接口和委托类型。通过使用 'out' 关键字注释泛型类型,您可以将其标记为泛型协变。例如,IEnumerable 泛型接口声明如下所示:

     IEnumerable(Of Out T)
    

    这意味着现在可以执行以下操作:

     Dim mylist As IEnumerable(Of Object) = new List<Product>()
    

    因此可以安全地将 IEnumerable(Of Product) 的列表分配给 IEnumerable(Of Object) 类型的变量。

    Here's an explanation of co- and contravariance in VB.Net

    所以,你可以做的是为通用表定义一个接口:

    Interface ITable(Of Out T)
    End Interface
    

    然后你可以在你的通用 Table 类中实现这个接口:

    Class Table(Of T)
        Implements ITable(Of T)
    End Class
    

    那么这将起作用:

    Function CreateTable(ByVal t As Type) As ITable(Of Object)
        Dim result As ITable(Of Object) 
        Dim type = GetType(Table(Of )).MakeGenericType(t)
        result = FormatterServices.GetUninitializedObject(type)
        Return result
    End Function
    

    当然,如果可能,最好使用 IEnumerable(Of T) 而不是 ITable(Of T)。

    【讨论】:

      【解决方案2】:

      尝试使整个方法通用(并使用函数而不是子方法):

      Public Function GetTable(Of T)() As Table(Of T)
      

      【讨论】:

        【解决方案3】:

        看看这些,看看我认为你在问什么的几个例子:

        【讨论】:

          猜你喜欢
          • 2021-05-03
          • 1970-01-01
          • 2020-07-12
          • 2019-05-23
          • 2022-01-12
          • 2022-08-18
          • 1970-01-01
          相关资源
          最近更新 更多