Как конвертировать делегат из c # в vb.net? - PullRequest
2 голосов
/ 24 августа 2009

У меня есть этот код, который я пытаюсь преобразовать из 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;
        }

Весь этот делегат сбивает меня с толку. Может кто-нибудь помочь мне преобразовать это? Или есть статья, которая объясняет, как это сделать?

Ответы [ 5 ]

8 голосов
/ 24 августа 2009

Это анонимная функция, и VB.Net не поддерживает подобные анонимные функции (при условии .Net 2.0, поскольку в .Net 3.5 это было бы написано как лямбда-выражение).

Лучшее, что вы можете сделать в VB.Net, это добавить анонимную функцию (делегат) в качестве отдельного метода в том же классе и использовать оператор AddressOf для ссылки на этот новый метод.


Обновление:
Повторное чтение вашего кода, перевод сложен, потому что ваш анонимный метод будет интерпретироваться как замыкание , и это означает, что компилятор 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

Обратите внимание, что этот перевод не проверен и, вероятно, неверен: точное преобразование может быть очень сложным.

6 голосов
/ 24 августа 2009

Мой любимый способ сделать это - скомпилировать в 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
1 голос
/ 24 августа 2009

Вот окончательный код, который я использовал:

    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 - так близко, просто нужна небольшая помощь. Спасибо!

1 голос
/ 24 августа 2009

SOmethiong, как должно быть:

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
0 голосов
/ 24 августа 2009

есть онлайн-конвертер 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...