VB.NET等效于C#“dynamic”与选项严格打开

在使用types安全的VB.NET(即使用Option Strict On时,是否存在与C#4“dynamic”关键字等效的内容?

相当于VB.NET中的Object,但带有Option Strict Off 。 使用Option Strict On没有等价的。 换句话说, dynamic关键字将Option Strict Off等效function带给了C#。

VB.NET总是有内置的“dynamic”function,最初称为后期绑定。 这个语法永远支持:

  Dim obj = new SomeComClass() obj.DoSomething() 

使用.NET和COM实现的代码,后者是最常见的用法。 C#中的dynamic关键字赋予它相同的function。 它确实在VB.NET版本10中得到了改变,但是现在也在使用DLR。 它增加了对Python和Ruby等语言实现的dynamic绑定支持。

语法是完全一样的,使用Dim关键字没有As。 然而,你将不得不使用Option Strict Off,Option Infer On可以软化这一点。 它确实表明C#使用特定的关键字来表示dynamic绑定是一个相当不错的举措。 Afaik所有在VB.NET中都这么做的请求,至今还没有被考虑,但没有计划。

如果您更喜欢Option Strict On,然后使用Partial Class关键字,那么您可以将一些代码移动到另一个源文件中,这可能是最有效的方法。

这将说明什么基本是说VB不与C#中有相同的粒度。 我在C#中有这段代码,它使用reflectiondynamic地在运行时调用一个方法:

 var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null); 

我这样做的原因是“GetSomeData”可以是许多方法中的任何一种,每个方法获得不同的数据。 在这里调用的方法依赖于在运行时传递给此对象的string参数,因此,“GetSomeData”的值在运行时会有所不同。

“GetSomeData”的签名是:

 public List<SomeResultSetClass> GetSomeData() 

调用的每个方法都返回某种List<T>对象。 接下来,我将listResult对象发送到名为Export的通用方法,如下所示:

 void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class; 

这是我们遇到问题的地方。 Invoke返回一个System.Objecttypes的对象。 当然, List<T>也是一个System.Object,但是暴露的接口是System.Object接口,而不是IList接口。 如果我尝试执行Export方法,那么:

 myExportObj.Export(listResult, parms.filePath, parms.fileType); 

代码无法编译。 错误是:

The type arguments for method '...Export<T>...' cannot be inferred from the usage. Try specifying the type arguments explicitly.

不用了,谢谢!! 问题是编译器无法findIList元数据,因为它正在查看System.Object接口。 现在,您可以创build一个新的List<T> ,将它分配给(List<Whatever>) listResult ,但是这首先破坏了dynamic调用的目的。

解决方法是将var更改为dynamic

 dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null); 

由于dynamic绕过编译时的静态types检查,所以我们不会收到编译错误。 然后,当dynamic对象传递给Export方法时,DLR(dynamic语言运行时)会查看它是否可隐式转换对象以满足方法签名的要求。 当然可以。

好的,这就是C#中的事情。 用VB,线路是这样的:

 Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing) 

如果使用Option Strict On,则按预期的那样,此行会使编译器不稳定。 closures它,它工作正常。 换句话说,在VB中,我必须closures包含该行的整个模块的types检查器。 没有比这更精细的粒度。

您可以打开选项推断和选项严格closures,仍然有一些非常接近。

有足够的方法来处理COM对象的晚期绑定和types安全的方法和属性( Option Strict On )。 这在使用Microsoft.VisualBasic.Interaction.CallByName和System.Type.InvokeMember方法时。 (或者在Option Strict Off创build一个单独的“部分”文件)。

但是处理来自VB.NET的后期绑定事件并不像C#中的dynamictypes那样简单。 您可以在VB.NET中的“ dynamic事件 ”中检查“hack”。

是的,ExpandoObject。

Dim DObj = New System.Dynamic.ExpandoObject()

DObj.A =“abc”

DObj.B = 123

Interesting Posts