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