Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#和#x27;动态';选择严格_C#_Vb.net_Dynamic_Option Strict - Fatal编程技术网

C#和#x27;动态';选择严格

C#和#x27;动态';选择严格,c#,vb.net,dynamic,option-strict,C#,Vb.net,Dynamic,Option Strict,在使用类型安全的VB.NET时,C#4“dynamic”关键字是否有等效项,即使用选项Strict On?等效项是VB.NET中的Object,但使用选项Strict Off。在选项严格限制的情况下没有等效项。换句话说,关键字将Option Strict关闭等效于C#的功能。您可以打开Option推断和关闭Option Strict,但仍然有非常接近的功能。VB.NET始终内置“动态”功能,最初称为后期绑定。此语法永远受支持: Dim obj = new SomeComClass() obj

在使用类型安全的VB.NET时,C#4“dynamic”关键字是否有等效项,即使用
选项Strict On

等效项是VB.NET中的Object,但使用
选项Strict Off
。在
选项严格限制的情况下
没有等效项。换句话说,关键字将Option Strict关闭等效于C#的功能。

您可以打开Option推断和关闭Option Strict,但仍然有非常接近的功能。

VB.NET始终内置“动态”功能,最初称为后期绑定。此语法永远受支持:

 Dim obj = new SomeComClass()
 obj.DoSomething()
致力于.NET和COM中实现的代码,后者是最常用的。C#中的dynamic关键字赋予了它同样的功能。它确实在VB.NET版本10中进行了更改,但是,它现在也在使用DLR。它为Python和Ruby等语言实现增加了对动态绑定的支持

语法完全相同,请使用Dim关键字而不使用As。但是,您必须使用
选项Strict Off
选项Infer On
可以稍微缓和这种打击。它确实表明C#使用特定关键字来表示动态绑定是一个非常好的举措。Afaik在VB.NET中执行此操作的所有请求都已被考虑,但尚未计划


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

有足够的方法处理具有后期绑定COM对象和类型安全的方法和属性(
Option Strict On
)。当使用Microsoft.VisualBasic.Interaction.CallByName和System.Type.InvokeMember方法时,会出现此问题。(或者创建一个单独的“部分”文件,其中
选项Strict
Off


但是用VB.NET的后期绑定处理事件并不像用C#中的动态类型那样简单。您可以在中检查“hack”以了解这一点。

这将演示Basic如何说明VB在这方面的粒度与C#不同。我有一段C#代码,它使用反射在运行时动态调用方法:

var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
我这样做的原因是“GetSomeData”可以是许多方法中的任何一种,每个方法都可以获得不同的数据。在这里调用哪个方法取决于在运行时传递到此对象的字符串参数,所以“GetSomeData”的值在运行时会有所不同

“GetSomeData”的签名为:

代码无法编译。错误是:

无法从用法推断方法“…导出…”的类型参数。尝试显式指定类型参数。

不用了,谢谢!!问题是编译器找不到IList元数据,因为它正在查看System.Object接口。现在,您可以创建一个新的
列表
,将
(List)listResult
分配给它,但这首先会破坏动态调用的目的

修复方法是将
var
更改为
dynamic

dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
由于dynamic在编译时绕过了静态类型检查,所以不会出现编译错误。然后,当动态对象传递给导出方法时,DLR(动态语言运行时)会查看是否可以隐式转换该对象以满足方法签名的要求。当然可以

好的,这就是C#中的工作原理。使用VB时,线路如下所示:

void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class;
Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing)
如果Option Strict处于启用状态,这一行将按预期扰乱编译器。关闭后,它工作正常。换句话说,在VB中,我必须关闭包含该行的整个模块的类型检查器。没有比这更精细的粒度了。

是的,ExpandoObject

Dim DObj=新系统.Dynamic.ExpandoObject()

DObj.A=“abc”

DObj.B=123


请注意,即使使用Option Strict on,您仍然可以使用ExpandooObject访问以下属性:

Dim doc = JsonConvert.DeserializeObject(Of ExpandoObject)("{""name"":""Bob""}")
Dim lookup as IDictionary(Of String, Object) = doc
lookup("name") ' Bob
Vb.Net中带有选项strict on的c#dynamic关键字的等价物作为一个NuGet包存在:dynametiy

安装包dynametiy后,可以编写如下Vb.Net代码:

Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Dynamic.InvokeMember(o, "Substring", 5)) ' writes 67890
    End Sub
End Module
或者更容易阅读:

Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    <Extension()>
    Public Function Substring(self As Object, offset As Integer) As String
        Return CType(Dynamic.InvokeMember(self, "Substring", offset), String)
    End Function

    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Substring(o, 5)) ' writes 67890
    End Sub
End Module
选项严格开启:选项推断开启:选项显式开启
进口动态
模块1
公共函数子字符串(self作为对象,offset作为整数)作为字符串
返回CType(Dynamic.InvokeMember(self,“Substring”,offset),字符串)
端函数
公用分干管()
Dim o=无
o=“1234567890”
Console.WriteLine(子字符串(o,5))'写入67890
端接头
端模块

使用VS2017和.net Framework 4.7.2进行测试。

VB是类型安全的,无论选项是严格打开还是关闭。阅读这里的含义@jdk好吧,我想我不得不同意。然而,我的意思是编译时检查类型安全,正如你可能已经猜到的那样…@jdk:每个人在谈论编程语言时使用的类型安全的定义是这样的:@jeroenh我受到启发,在microsoftconnect上发布了一条建议,如果VB在C#中有类似
dynamic
的东西,那就太好了。任何同意或不同意的人都可以投票或评论Microsoft VB spec lead。VB团队的临时评估是“VB总是有自己的形式通过对象进行后期绑定。虽然遗憾的是您不能将后期绑定的范围缩小到小于文件粒度,但这似乎还不足以证明第二种形式的后期绑定是合理的。”亲爱的读者,如果你对此有强烈的感受,为什么不在博客上留言,或者在我之前的评论中提到的Microsoft Connect问题。@Hans Passant:我知道,C#dynamic与VB的“后期绑定”并不完全相同。在C#中,使用dynamic关键字,我可以非常明确地了解程序的动态部分。对我来说,这就像告诉编译器:“嘿,我知道我在为程序的这个特定部分做什么。”。使用VB.Net,我必须
Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Dynamic.InvokeMember(o, "Substring", 5)) ' writes 67890
    End Sub
End Module
Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    <Extension()>
    Public Function Substring(self As Object, offset As Integer) As String
        Return CType(Dynamic.InvokeMember(self, "Substring", offset), String)
    End Function

    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Substring(o, 5)) ' writes 67890
    End Sub
End Module