Matt Wilko Matt Wilko - 5 months ago 17
Vb.net Question

Can't seem to Pass EventArgs By Reference

I have a class that raises an event. I want the subscriber to be able to modify the values being passed in the EventArgs.

In the class that raises the events:

class Factory
{
public event EventHandler<MessageReceivedEventArgs> MessageReceived;

private IServerLib _myObject;

public void Connect()
{
_myObject = new ServerLib();
_myObject.AddMessageReceivedHandler((short terminal, ref string message, ref short functionNo) =>
{
MessageReceivedEventArgs args = new MessageReceivedEventArgs { Terminal = terminal, Message = message, FunctionNo = functionNo };
MessageReceivedEvent(ref args);
});
}

private void MessageReceivedEvent(ref MessageReceivedEventArgs args)
{
EventHandler<MessageReceivedEventArgs> handler = MessageReceived;
if (handler != null)
{
handler(this, args);
}
}

public class MessageReceivedEventArgs : EventArgs
{
public short Terminal { get; set; }
public string Message { get; set; }
public short FunctionNo { get; set; }
}
}


interface IServerLib
{
void AddMessageReceivedHandler(MessageReceivedEventHandler action);
}
public delegate void MessageReceivedEventHandler(short terminal, ref string message, ref short functionNo);


The subscriber (which happens to be VB) looks like this:

Dim WithEvents _va As MyAssembly.MyClass

Private Sub _va_MessageReceived(sender As Object, e As Factory.MessageReceivedEventArgs) Handles _va.MessageReceived
Debug.WriteLine($"Message: {e.Message} Terminal: {e.Terminal} Function: {e.FunctionNo}")
If e.Message = "1" Then
e.Message = ""
e.FunctionNo = 0
Debug.WriteLine("Cancelled")
End If
End Sub


This raises the event, but setting the e.Message and e.Function do not seem to set the values. Am I doing something wrong?

Answer

The problem lies in the use of this line:

var args = new MessageReceivedEventArgs
           { Terminal = terminal, Message = message, FunctionNo = functionNo };

It copiex all variables to the event args class. Changing it there doesn't automatically change it on the other end (where you added ref). Not a nice solution, but to proof to you this is the issue, add this after handler(this, args):

message = args.Message;
functionNo = args.FunctionNo;

This will cause the refs to overwrite the values.

Comments