Динамические функции платформы .NET 4.0 в VB с опцией Strict On?
Есть ли способ использовать новые динамические функции в инфраструктуре 4.0, например ExpandoObject
в VB.NET без установки Option Strict Off
? С помощью С# вы теряете тип безопасности только с переменными, которые вы определенно объявляете как dynamic
. Но с VB единственным способом, который я нашел использовать эти функции, является старый трюк Option Strict Off
, который был с VB.NET с самого начала. Без опции 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
, и снизить риск потери безопасности всего типа? Частичные классы? Или я просто не буду так беспокоиться о безопасности типов в этом случае?
Ответы
Ответ 1
Кажется, вы не можете без необходимости отключить параметр Strict.
Я буду исследовать еще немного.
Edit
После прохождения какой-либо документации по ExpandoObject
, она появляется в С# для COM и Office Interop. Традиционно в VB.NET для этих целей использовался Object
, и для этого потребовалось бы отключить параметр Strict.
Чтобы ответить на ваш вопрос, это означает, что вы можете использовать динамические типы в VB.NET с помощью типа Object
вместо ExpandoObject
[если такой тип существует в VB.NET], установите Option Infer On
и Option Strict On или Off.
Вы также можете рассмотреть возможность использования частичных классов для локализации вашего кода, отличного от параметра Strict, для определенных файлов.
Рекомендуемое чтение
Ответ 2
Нет. Это своего рода современная поздняя привязка.
Ответ 3
Я не пробовал это, и это было бы не очень красиво, но вы должны использовать 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
Как я уже сказал, это некрасиво.