在C#中将Handler添加到Dynamic无法转换为VB Object AddHandler

时间:2015-09-23 15:52:15

标签: c# .net vb.net delegates c#-to-vb.net

我有一些C#代码,我正在转换为VB.NET。

在课堂上我有以下内容:

public class ServiceCapServerLib : ICapServerLib
{
    private readonly dynamic _lib;

    public void AddMessageReceivedHandler(ICapServerLib.MessageReceivedEventHandler action)
    {
        _lib.MessageReceived += action;
    }
}

我的VB相当于:

Option Strict Off

Public Class ServerCapServerLib
    Implements ICapServerLib

    Private ReadOnly _lib As Object

    Public Sub AddMessageReceivedHandler(ByVal action As ICapServerLib.MessageReceivedEventHandler) Implements ICapServerLib.AddMessageReceivedHandler
        AddHandler _lib.MessageReceived, action
    End Sub
End Class

但它无法使用&#34编译; MessageReceived不是Object"的成员。显然是这种情况,但C#代码有效,所以我错过了什么?

编辑: 我也试过了AddHandler _lib.MessageReceived, AddressOf action,但这会给出错误"' AddressOf'操作数必须是方法的名称(没有括号)"

1 个答案:

答案 0 :(得分:2)

您尝试的内容无效,因为C#中的dynamic与使用object的VB.NET中的Option Strict Off相同并不完全正确。

dynamic in C#

  

动态类型使其发生的操作能够绕过   编译时类型检查。相反,这些操作在解决   运行时间。

对于Visual Studio,dynamic变量可以是任何东西,这就是为什么它永远不会抱怨给定的属性(或事件,就像在这种情况下)。您的第一个代码很好,因为它接受_lib有一个名为MessageReceived的事件(不执行检查)。

Option Strict Off in VB.NET

  

(启用时)将隐式数据类型转换限制为仅扩展转换,   不允许后期绑定,并禁止导致的隐式输入   对象类型。

这意味着,Option Strict Off,Visual Studio"抱怨较少"在某些情况下。要理解前面提到的不太准确的语句的确切含义,您可以深入分析每个方案的确切定义(例如early & late binding)或者相信Visual Studio告诉您的内容。根据您选择的选项,您将得出结论:在这种特定情况下,在将事件带入图片之前,必须将_lib转换/转换为相应的类型(ICapServerLib)。 / p>

请注意,.NET 4.0引入了System.Dynamic命名空间(与C#dynamic同时)。 VB.NET& C#可以不受任何限制地处理该命名空间的内容(例如,https://msdn.microsoft.com/en-us/library/ee461504(v=vs.110).aspx)。

我对上述命名空间没有太多经验,并且不确定您是否可以完美地模拟VB.NET中的C#dynamic行为。但我确定一些事情:Option Strict Off + Object与C#中的dynamic不同。另请注意,C#中不存在VB.NET WithEvents,这就是为什么VB.NET事件的处理方式与其他属性不同(C#中不太可能)。

注意:Hans Passant已对此问题发表评论,强调VB.NET从未支持过时绑定事件。我无法(完全)确认/驳回这样的陈述,但会认为这是正确的。在这种情况下,无法将原始C#代码直接转换为VB.NET。