Динамические функции фреймворка .NET 4.0 в VB с Option Strict On? - PullRequest
16 голосов
/ 22 июля 2010

Есть ли способ использовать новые динамические функции в платформе 4.0, например ExpandoObject в VB.NET, без установки 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 и снизить риск потери безопасности всех типов? Частичные занятия? Или мне просто не стоит так беспокоиться о безопасности типов в этом случае?

Ответы [ 3 ]

7 голосов
/ 01 августа 2010

Похоже, вы не сможете отключить Option Strict. Я исследую еще немного.


Редактировать


После просмотра некоторой документации по ExpandoObject выясняется, что она используется в C # для COM и Office Interop. Традиционно в VB.NET Object использовался для таких целей, и для этого потребовалось бы отключить Option Strict.

Чтобы ответить на ваш вопрос, это означает, что вы можете использовать динамические типы в VB.NET, используя тип Object вместо ExpandoObject [если такой тип существует в VB.NET], установите Option Infer On и Опция Строгое Вкл. Или Выкл. .
Вы также можете рассмотреть возможность использования частичных классов для локализации вашего кода, не являющегося Option Strict, для конкретных файлов.



Рекомендуемое чтение

3 голосов
/ 31 августа 2010

Я не пробовал это, и это было бы не красиво, но вы должны быть в состоянии использовать 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  

Как я уже сказал, это не красиво.

3 голосов
/ 01 августа 2010

Нет. Это своего рода поздний переплет современного дня.

...