16

有什么方法可以像ExpandoObject在 VB.NET 中一样使用 4.0 框架中的新动态功能而无需设置Option Strict Off?在 C# 中,只有明确声明为dynamic. 但是对于 VB,我发现使用这些功能的唯一方法是使用Option Strict Off从一开始就存在于 VB.NET 中的旧技巧。如果没有 Option Strict,文件中的所有内容都会被模糊类型污染,如下所示:

Option Explicit On
Option Strict Off
Option Infer On

Partial Public Class ClassX

   Public Sub TestDynamic()
      Dim dyn As Object = New System.Dynamic.ExpandoObject()
      Dim a As String = 1 ''# Ew!
      Dim obj As Object = "999"

      dyn.Str = a   ''# a is a string, remember?  Even though it has a number
      ''# dyn.Str = 1 : Type = System.String
      Console.WriteLine("dyn.Str = {0} : Type = {1}", dyn.Str, dyn.Str.GetType().ToString())

      dyn.Num = 123
      ''# dyn.Num = 123 : Type = System.Int32
      Console.WriteLine("dyn.Num = {0} : Type = {1}", dyn.Num, dyn.Num.GetType().ToString())

      dyn.Dbl = obj / 9
      ''# dyn.Dbl = 111 : Type = System.Double
      Console.WriteLine("dyn.Dbl = {0} : Type = {1}", dyn.Dbl, dyn.Dbl.GetType().ToString())

      dyn.Obj = obj
      ''# dyn.Obj = 999 : Type = System.String
      Console.WriteLine("dyn.Obj = {0} : Type = {1}", dyn.Obj, dyn.Obj.GetType().ToString())

      dyn.Dte = #5/5/1955#
      ''# dyn.Dte = 7/7/1977 12:00:00 AM : Type = System.DateTime
      Console.WriteLine("dyn.Dte = {0} : Type = {1}", dyn.Dte, dyn.Dte.GetType().ToString())

      AmICalled(dyn.Num)
      AmICalled(dyn.Obj)
      AmICalled(dyn.Str)
      AmICalled(dyn.Dbl)

      Try
         AmICalled(dyn.Dte)
      Catch
         Console.WriteLine("Dates don't convert to ints I guess... but we don't know that 'till runtime")
      End Try

      Console.WriteLine(dyn.Num + dyn.Str) ' 124!?
      Console.WriteLine(dyn.Num & dyn.Str) ' 1231!?

   End Sub

   Private Sub AmICalled(ByVal i As Integer)
      Console.WriteLine("AmICalled was called with: " & i)
   End Sub

End Class

这真的正确吗?而且,如果是这样,那么仍然使用诸如此类的东西ExpandoObject并减轻失去所有类型安全性的风险的最佳方法是什么?部分课程?还是在这种情况下我不应该那么担心类型安全?

4

3 回答 3

8

看来您必须关闭 Option Strict 才能做到这一点。不过我会再研究一些。


编辑


在浏览了一些文档之后ExpandoObject,它似乎在 C# 中用于 COM 和 Office 互操作。传统上,在 VB.NET 中,Object用于此类目的并且需要您关闭 Option Strict。

要回答您的问题,这意味着您可以在 VB.NET 中使用动态类型,方法是使用Object类型而不是ExpandoObject[如果 VB.NET 中存在这种类型],设置Option Infer OnOption Strict On 或 Off
您还可以考虑使用部分类将您的非 Option Strict 代码本地化到特定文件。



推荐阅读

于 2010-08-01T02:51:06.360 回答
4

这个我没试过,不会很漂亮,但你应该可以使用CallByName.

调整你的例子

Partial Public Class ClassX  

   Public Sub TestDynamic()  
      Dim dyn As Object = New System.Dynamic.ExpandoObject()  
      Dim a As String = "1" ''# Option Strict is on  
      Dim obj As Object = "999"  

      ''# dyn.Str = a  
      CallByName(dyn, "Str", CallType.Set, a) 
      Console.WriteLine("dyn.Str = {0} : Type = {1}", 
        CallByName(dyn, "Str", CallType.Get, a), 
        CallByName(dyn, "Str", CallType.Get, a).GetType().ToString()
      )     

      ''# etc etc... I can't face any more of that  

正如我所说,它并不漂亮。

于 2010-08-31T12:15:59.133 回答
4

不,这是一种现代的后期装订。

于 2010-08-01T02:23:32.710 回答