1

I have a text file that I am compiling into an assembly use the VBCodeProvider class

The file looks like this:

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

Here is the compile code:

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

What I want to do is to modify the value of the comment String inside the method, so that after I call it from code I can inspect the value:

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

However comment is always "Foo" (message box shows "Not Allowed"), so it appears that the ByRef modifier is not working

If I use the same method in my code comment is correctly modified.

Matt Wilko
  • 26,994
  • 10
  • 93
  • 143

1 Answers1

2

However comment is always "Foo" (message box shows "Not Allowed"), so it appears that the ByRef modifier is not working

It is, but you're using it incorrectly, with incorrect expectations :)

When you create the argument array, you're copying the value of comment into the array. After the method has completed, you no longer have access to the array, so you can't see that it's changed. That change in the array won't affect the value of comment, but demonstrates the ByRef nature. So what you want is:

Dim arguments As Object() = New Object() { 1234, comment }
method.Invoke(_scriptClass, arguments)
Debug.WriteLine(arguments(1))
Matt Wilko
  • 26,994
  • 10
  • 93
  • 143
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • (Apologies for any failures in the syntax of the first line, by the way. I can't easily check it right now.) – Jon Skeet Feb 11 '14 at 12:06
  • Yes I see that makes sense to me. Yes I figured it out:- there was an extra closing bracket in your code after the `comment }` – Matt Wilko Feb 11 '14 at 12:07
  • @MattWilko: Ah - that was left over from copying the end of the method invocation :) – Jon Skeet Feb 11 '14 at 12:12