Carlos
Carlos

Reputation: 1822

C# Delegate from VB.NET

I have a legacy solution which has some C# projects (newest ones) and some VB projects (oldest ones). I know it is not a good practice, but it is what I have now, so I have to deal with it.

In a C# project I have some code like this:

public class MyObjectClass 
{
    ... more code here ...
    public delegate void SelectedItemChange(IMyInterface oldItem, IMyInterface newItem);
    public virtual SelectedItemChange SelectedItemChanged { get; set; }
}

And this works like a charm when I use it from another C# project this way:

public class MySecondaryClass
{
    ... more code here ...
    MyObjectClass MyObject = new();
    MyObject.SelectedItemChanged += (sender, args) => { DoSomething(); };
}

So far, so good. The problem is when I have to use the same delegate from a VB.NET project. I have tried this:

Public Class MySecondaryClassVB
   ... more code here ...
   Dim MyObject as MyObjectClass = New MyObjectClass()
   AddHandler MyObject.SelectedItemChanged, Sub(sender As Object, args As EventArgs)
                                                 DoSomething()
                                            End Sub
End Class

But SelectedItemChanged appears in Visual Studio underlined in red with the next error:

'SelectedItemChanged' is not an event of 'MyObjectClass'

I am not able to understand why it works in C# and not in VB.NET, so I guess my AddHandler syntax is not correct. What is the right syntax for this? What am I doing wrong?

Thank you

UPDATE: Maybe it is useful to understand the problem. The real MyObjectClass is there I emit the event:

public class MyObjectClass 
{
    ... more code here ...

    private IMyInterface _selectedItem;
    public IMyInterface SelectedItem
    {
        get => _selectedItem;
        set
        {
            IMyInterface oldSelectedItem = _selectedItem;
            _selectedItem = value;
            SelectedItemChanged?.Invoke(oldSelectedItem, _selectedItem);
            SetProperty(ref _selectedItem, value);
        }
    }

    public delegate void SelectedItemChange(IMyInterface oldItem, IMyInterface newItem);
    public virtual SelectedItemChange SelectedItemChanged { get; set; }
}

Then I want to subscribe to that event from a C# project (and I do it with no problem), or from a VB.NET project (and I am not able to).

Upvotes: 1

Views: 328

Answers (3)

user17922293
user17922293

Reputation:

If that SelectedItemChanged will only ever refer to a single delegate then just create one and assign it, just as you would for any other property referring to any other object:

MyObject.SelectedItemChanged = New SelectedItemChange(Sub(sender, args) DoSomething())

If it might refer to multiple delegates then you can do explicitly what the C# += operator is doing implicitly:

MyObject.SelectedItemChanged = [Delegate].Combine(MyObject.SelectedItemChanged, New SelectedItemChange(Sub(sender, args) DoSomething()))

It's worth noting here that your delegate is specific declared with two parameters of type IMyInterface. That means that, in this code:

MyObject.SelectedItemChanged += (sender, args) => { DoSomething(); };

both sender and args are inferred as that type. They are NOT object and EventArgs, as you have assumed for your VB code. That's an example of how the C# code is garbage.

Upvotes: 1

user17805377
user17805377

Reputation:

Try this:

Public Event SelectedItemChange_Event As SelectedItemChange

Upvotes: 0

zTim
zTim

Reputation: 78

It´s because SelectedItemChange is not an event. You need to declare it as event

public event SelectedItemChange SelectedItemChange_Event;

Your AddHanler Syntax in VB is correct

Upvotes: 1

Related Questions