2010-07-22 1 views
15

Есть ли способ использовать новые динамические функции в фреймворке 4.0, например ExpandoObject, в VB.NET без настройки Option Strict Off? С C# вы теряете тип безопасности только с переменными, которые вы конкретно заявляете как dynamic. Но с VB единственным способом, который я нашел использовать эти функции, является старый трюк Option Strict Off, который был с VB.NET с самого начала. Без Option Strict, все в файле загрязнена нечеткой набрав примерно так:Динамические функции платформы .NET 4.0 в VB с опцией Strict On?

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

Хорошо, я начал щедрость. Есть ли способ, которым разработчики VB.NET могут использовать новые динамические функции .NET 4.0 без поворота Option Strict Off и, таким образом, потерять безопасность типа для всего, а не только для одной динамической переменной? – mattmc3

+0

Я отправил запрос на эту функцию против VB.Net на [Microsoft Connect] (https://connect.microsoft.com/VisualStudio/feedback/details/591963/please-give-vb-net-some-equivalent-for- с динамической с-опционным строгим на). Любой, кто имеет мнение до или против, может голосовать там. Существует также это [сообщение в блоге] (http://blogs.msdn.com/b/lucian/archive/2010/01/28/core2-dynamic-pseudo-type-scoped-late-binding.aspx) из команды VB. – MarkJ

+0

Кстати, есть также [дублированный вопрос] (http://stackoverflow.com/questions/2889974/vb-net-equivalent-for-c-dynamic-with-option-strict-on) – MarkJ

ответ

6

Кажется, вы не можете без необходимости отключить параметр Strict. Я еще немного изучу.


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


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

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



Рекомендуемая литература

3

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

2

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

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

Смежные вопросы