Как мне заставить ByRef Arguments работать в динамически создаваемой сборке с Method.Invoke

У меня есть текстовый файл, который я компилирую в сборку с использованием класса VBCodeProvider

Файл выглядит так:

Imports System
Imports System.Data
Imports System.Windows.Forms

Class Script

    Public Sub AfterClockIn(ByVal clockNo As Integer, ByRef comment As String)
        If clockNo = 1234 Then
            comment = "Not allowed"
            MessageBox.Show(comment)
        End If
    End Sub

End Class

Вот код компиляции:

Private _scriptClass As Object
Private _scriptClassType As Type

Dim codeProvider As New Microsoft.VisualBasic.VBCodeProvider()
Dim optParams As New CompilerParameters
optParams.CompilerOptions = "/t:library"
optParams.GenerateInMemory = True
Dim results As CompilerResults = codeProvider.CompileAssemblyFromSource(optParams, code.ToString)
Dim assy As System.Reflection.Assembly = results.CompiledAssembly
_scriptClass = assy.CreateInstance("Script")
_scriptClassType = _scriptClass.GetType

Я хочу изменить значение String комментария внутри метода, чтобы после его вызова из кода я смог проверить значение:

Dim comment As String = "Foo"
Dim method As MethodInfo = _scriptClassType.GetMethod("AfterClockIn")
method.Invoke(_scriptClass, New Object() {1234, comment})
Debug.WriteLine(comment)

Однако комментарий всегда "Foo" (окно сообщения показывает "Not Allowed"), поэтому кажется, что модификатор ByRef не работает

Если я использую тот же метод в моем коде comment правильно изменен.

1 ответ

Решение

Однако комментарий всегда "Foo" (в окне сообщения отображается "Not Allowed"), поэтому кажется, что модификатор ByRef не работает

Это так, но вы используете это неправильно, с неверными ожиданиями:)

Когда вы создаете массив аргументов, вы копируете значение comment в массив. После завершения метода у вас больше нет доступа к массиву, поэтому вы не можете видеть, что он изменился. Это изменение в массиве не повлияет на значение comment, но демонстрирует ByRef природа. Итак, что вы хотите, это:

Dim arguments As Object() = New Object() { 1234, comment }
method.Invoke(_scriptClass, arguments)
Debug.WriteLine(arguments(1))
Другие вопросы по тегам