2

I'm developing some Boo code that needs to be notified by an existing delegate in C#. I'm getting a Boo compilation error in the constructor of the ActionBoo class. Please see the error message along with every alternative I tried.

# Boo
import System

class ActionBoo:
    def constructor():
        # Alternative #1
        # ActionBoo.boo(9,25): BCE0051: Operator '+' cannot be used with a left hand side of type 'System.Action' and a right hand side of type 'callable(int) as void'.
        ActionCS.action += Boo

        # Alternative #2
        # ActionBoo.boo(13,25): BCE0051: Operator '+' cannot be used with a left hand side of type 'System.Action' and a right hand side of type 'System.Action'.
        ActionCS.action += Action[of int](Boo)

        # Alternative #3
        # This works, but it resets the delegate already set up in C#
        ActionCS.action = Boo

    def Boo(boo as int):
        print 'Boo: ' + boo

actioncs = ActionCS()
actionBoo = ActionBoo()
ActionCS.action(3)

ActionCS is an existing C# code with a multicast delegate. Here is a simplified version of the original code:

// C#
using System;

public class ActionCS
{
    public static Action<int> action;

    public ActionCS()
    {
        action += Foo;
        action += Bar;
    }

    public void Foo(int foo)
    {
        Console.WriteLine("Foo: " + foo);
    }

    public void Bar(int bar)
    {
        Console.WriteLine("Bar: " + bar);
    }

    public static void Main(string[] args)
    {
        ActionCS actioncs = new ActionCS();
        action(5);
    }
}

Here is how I compiled with Mono (v2.10.9-0) and Boo (v0.9.4.9) on Linux:

$ mcs ActionCS.cs
$ mono booc.exe -r:ActionCS.exe ActionBoo.boo

The C# code and Boo's "Alternative #3" run fine by calling:

$ mono ActionCS.exe
Foo: 5
Bar: 5
$ env MONO_PATH=$MONO_PATH:$BOO_HOME/bin mono ActionBoo.exe
Boo: 3

Does anyone know how to fix the Boo code?

mmmaes
  • 23
  • 2
  • It is just the "Boo" code that is failing here, right? An answer was added (now deleted) talking about multi-cast; *that bit* was wrong (all delegates in .NET are multi-cast), but: does adding the `event` keyword fix it (i.e. `public static event Action action;`? I wonder whether "Boo" only works with formal `event`s, and doesn't work with naked delegate fields – Marc Gravell Nov 18 '13 at 12:16
  • 1
    btw, static events are a really good way to cause memory leaks – Marc Gravell Nov 18 '13 at 12:16
  • Changing to an event compiled and worked. However I can't really change the production C# code. Thank you for the extra information, I'll investigate about the memory leak. – mmmaes Nov 18 '13 at 12:32
  • For info, the "memory leak" issue is only a problem if there are short-lived objects that subscribe to the event but never unsubscribe themselves. The event will mean that they remain reachable (and uncollected) for the duration of the `AppDomain`. It would also make *invoking* the handler progressively slower as the list gets longer. If you aren't creating lots of objects that subscribe to the event, it probably isn't an issue. – Marc Gravell Nov 18 '13 at 12:43

1 Answers1

1

In C# += is just syntactic sugar for Delegate.Combine, so you could probably use that instead:

ActionCS.action = Delegate.Combine(ActionCS.action, Action[of int](Boo))

(note that I don't know anything about Boo specifically, only about .NET in general, so this is just an educated guess)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758