【问题标题】:How to convert delegate from c# to vb.net?如何将委托从 c# 转换为 vb.net?
【发布时间】:2009-08-24 14:54:40
【问题描述】:

我有这段代码,我正在尝试从 C# 转换为 VB.net:

public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            // Create a new, STA thread
            object[] staOutputs = null;
            object retval = null;
            Thread thread = new Thread(
                delegate(){
                    retval = _innerInvoker.Invoke(instance, inputs, out staOutputs);
                });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
            outputs = staOutputs;
            return retval;
        }

整个代表的事情让我失望。谁能帮我转换一下?或者有没有解释如何做到这一点的文章?

【问题讨论】:

    标签: c# vb.net delegates


    【解决方案1】:

    这是一个匿名函数,而 VB.Net 不支持这样的匿名函数(假设 .Net 2.0,因为在 .Net 3.5 中将被写为 lambda 表达式)。

    您可以在 VB.Net 中做的最好的事情是将匿名函数(委托)作为一个单独的方法添加到同一类中,并使用 AddressOf 运算符来引用这个新方法。


    更新:
    再次阅读您的代码,翻译很复杂,因为您的匿名方法将被解释为 closure,这意味着 C# 编译器在将代码转换为 IL 之前会对代码进行复杂的转换;创建一个全新的类是为了捕获(关闭)方法中引用的局部变量:

    Class InnerInvokerClosure
        Public instance As Object
        Public inputs() As Object
        Public staOutputs() As Object
        Public retValue As Object
    
        Public _innerInvoker As SomeDelegateType
    
        Sub New(ByRef instance as Object, ByRef inputs() as Object, ByRef staOutputs() As Object, ByRef retValue As Object, ByRef _innerInvoker As SomeDelegateType)
            Me.instance = instance
            Me.inputs = inputs
            Me.staOoutputs = staOutputs
            Me.retValue = retValue
    
            Me._innerInvoker = _innerInvoker
        End Sub
    
        Public Function Invoke() As Object
            retValue = _innerInvoker.Invoke(instance, inputs, staOutputs);
        End Function
    
    End Class
    
    Public Function Invoke(ByVal instance As Object, ByVal inputs() as Object, ByRef outputs() As Object) As Object
        Dim closure As New InnerInvokerClosure(instance, inputs, Nothing, Nothing, _innerInvoker)
    
        Dim t As New Thread(AddressOf closure.Invoke)
        t.SetApartmentState(ApartmentState.STA)
        t.Start()
        t.Join()
    
        outputs = closure.staOutputs
        return closure.retValue      
    End Function
    

    请注意,此翻译未经测试,可能是错误的:确切的转换可能非常复杂。

    【讨论】:

    • 你能给我一个 sudo 代码的例子吗?仍然很难理解这个......
    【解决方案2】:

    我最喜欢的方法是在 C# 中编译,然后使用反射器查看它在其他 dotNET 语言中的样子。

    Friend Class Program
    ' Methods '
    Private Shared Function Foo(ByVal instance As Object, ByVal inputs As Object(), <Out> ByRef outputs As Object()) As Object
        outputs = Nothing
        Return Nothing
    End Function
    
    Public Function Invoke(ByVal instance As Object, ByVal inputs As Object(), <Out> ByRef outputs As Object()) As Object
        Dim staOutputs As Object() = Nothing
        Dim retval As Object = Nothing
        Dim thread As New Thread(Function 
            retval = Me._innerInvoker.Invoke(instance, inputs, staOutputs)
        End Function)
        thread.SetApartmentState(ApartmentState.STA)
        thread.Start
        thread.Join
        outputs = staOutputs
        Return retval
    End Function
    
    ' Fields '
    Private _innerInvoker As MyInvoker = New MyInvoker(AddressOf Program.Foo)
    End Class
    
    
    <CompilerGenerated> _
    Private NotInheritable Class <>c__DisplayClass1
    ' Methods '
    Public Sub <Invoke>b__0()
        Me.retval = Me.<>4__this._innerInvoker.Invoke(Me.instance, Me.inputs, Me.staOutputs)
    End Sub
    
    
    ' Fields '
    Public <>4__this As Program
    Public inputs As Object()
    Public instance As Object
    Public retval As Object
    Public staOutputs As Object()
    End Class
    

    【讨论】:

      【解决方案3】:

      这是我使用的最终代码:

          Public Function Invoke(ByVal instance As Object, ByVal inputs As Object(), ByRef outputs As Object()) As Object Implements System.ServiceModel.Dispatcher.IOperationInvoker.Invoke
              Dim staOutputs As Object() = Nothing
              Dim retval As Object = Nothing
              Dim thread As New Thread(AddressOf DoWork)
              _instance = instance
              _inputs = inputs
              _staOutPuts = staOutputs
              thread.SetApartmentState(ApartmentState.STA)
              thread.Start()
              thread.Join()
              outputs = staOutputs
              Return retval
          End Function
      
          Private Function DoWork() As Object
              Return _innerInvoker.Invoke(_instance, _inputs, _staOutPuts)
          End Function
      

      @Rune FS - 如此接近,只需要一点帮助。谢谢!

      【讨论】:

      • 从未编写过单个 VB.NET 程序的代码 我对结果相当满意,哈哈
      【解决方案4】:

      应该是这样的:(其中 _ 是私有字段(这不是生产 rdy,但希望完全给你这个想法)

      Public Function Invoke(instance As Object, inputs As Object(), ByRef outputs As Object()) As Object
              ' Create a new, STA thread
              Dim staOutputs As Object() = Nothing
              Dim retval As Object = Nothing
              Dim thread As New Thread(AddressOf(Do))
      
              _instance = instance
              _inputs = inputs
              _staOutPuts = staOutputs
              thread.SetApartmentState(ApartmentState.STA)
              thread.Start()
              thread.Join()
              outputs = staOutputs
              Return retval
          End Function
      
          private Function Do() as Object
          Return _innerInvoker.Invoke(_instance, _inputs, _staOutputs)
          end Function
      

      【讨论】:

        【解决方案5】:

        有一个在线 C# 到 VB 转换器(反之亦然)位于 http://converter.telerik.com/

        我把你的代码贴在那里....我不知道这是否是有效的 VB 或者它是否可以工作,但你可以试一试。

        Public Function Invoke(instance As Object, inputs As Object(), ByRef outputs As Object()) As Object
            ' Create a new, STA thread
            Dim staOutputs As Object() = Nothing
            Dim retval As Object = Nothing
            Dim thread As New Thread(Function() Do
                retval = _innerInvoker.Invoke(instance, inputs, staOutputs)
            End Function)
            thread.SetApartmentState(ApartmentState.STA)
            thread.Start()
            thread.Join()
            outputs = staOutputs
            Return retval
        End Function
        

        【讨论】:

        • 同意,我去的第一个地方是一个 c# 到 vb.net 的转换器。它基本上给我一个错误:VB 不支持带有语句体的匿名方法/lambda 表达式
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多