有没有办法在VB.NET中使用4.0框架中的新动态功能,如ExpandoObject
而不设置Option Strict Off
?使用C#,您将使用明确声明为dynamic
的变量丢失类型安全性 。但是使用VB,我发现使用这些功能的唯一方法是使用从一开始就在VB.NET中使用的旧Option Strict Off
技巧。如果没有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
之类的东西的最佳方法是什么,并降低失去所有类型安全的风险?部分课程?或者我不应该在这种情况下担心类型安全吗?
答案 0 :(得分:7)
看来你不能不必关闭Option Strict。 我会研究一些。
修改强>
在查看ExpandoObject
上的一些文档之后,它似乎在C#中用于COM和Office Interop。传统上,在VB.NET中,Object
用于此类目的,并且需要您关闭Option Strict。
要回答您的问题,这意味着您可以使用Object
类型而不是ExpandoObject
[如果VB.NET中存在此类型],在VB.NET中使用动态类型,设置{ {1}}和选项严格打开或关闭
您还可以考虑使用部分类将非Option Strict代码本地化为特定文件。
推荐阅读
答案 1 :(得分:3)
没有。这有点像现代晚期的约束。
答案 2 :(得分:3)
我没有试过这个,它不会很漂亮,但你应该能够use 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
正如我所说,它并不漂亮。