2014-02-11 3 views
1

У меня есть текстовый файл, который я компиляции в сборку использовать класс VBCodeProviderКак я могу получить ByRef Доводы работать в динамически созданной сборке с Method.Invoke

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

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 

То, что я хочу сделать, это изменить значение комментария строки внутри метода, так что после того, как я называю это из кода я могу проверить Валу е:

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 правильно изменен.

ответ

2

Однако комментарий всегда «Foo» (окно сообщений показывает «Не разрешено»), так что кажется, что модификатор ByRef не работает

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

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

Dim arguments As Object() = New Object() { 1234, comment } 
method.Invoke(_scriptClass, arguments) 
Debug.WriteLine(arguments(1)) 
+0

(. Извиняюсь за ошибки в синтаксисе первой линии, кстати, я не могу легко проверить это прямо сейчас.) –

+0

Да я вижу, что имеет смысл для меня. Да, я понял: в вашем коде появилась дополнительная закрывающая скобка после 'comment}' –

+0

@MattWilko: Ah - что осталось от копирования конца вызова метода :) –