By the way, I fixed this by just overloading the "+" operator the normal way C# 
operators are overloaded, had it accept "object" on the right-hand-side so 
Python functions would make their way into it, and then used 
ObjectOperations.ConvertTo to convert the Python function to a 
System.EventHandler.

From: Jimmy Schementi
Sent: Tuesday, February 16, 2010 12:09 AM
To: Discussion of IronPython
Subject: RE: Monkey-patching CLR types


Dino Viehland wrote:

> If you strongly type handler to a delegate type IronPython should convert the

> function to the delegate type on the call.



Unfortunately it doesn't seem to :(. I repro'd that it doesn't on the desktop 
as well as in Silverlight; here's a desktop repro:



>>> import clr

>>> clr.AddReferenceToFile("pyext")

>>> import pyext

>>> t = pyext.TestClass()

>>> def foo(s, e): pass

...

>>> import System

>>> t.AttachEvent("foo", System.EventHandler(foo))

foo hooked!

>>> t.foo += foo

Traceback (most recent call last):

  File "<stdin>", line unknown, in <module>

TypeError: unsupported operand type(s) for +=: 'MyEvent' and 'function'



Also, when using a EventHandler as the right-hand-side of the +=, the 
AttachEvent method gets called, but still complains that the "foo" attribute 
doesn't exist:



>>> t.foo += System.EventHandler(foo)

foo hooked!

Traceback (most recent call last):

  File "<stdin>", line unknown, in <module>

AttributeError: 'TestClass' object has no attribute 'foo'



Any ideas? Here's the pyext.cs stub that I used:



//

// pyext.cs

//



using Microsoft.Scripting.Runtime;

using System;

using Microsoft.Scripting.Utils;

using System.Runtime.CompilerServices;



[assembly: ExtensionType(typeof(pyext.TestClass), 
typeof(pyext.TestClassExtension))]



namespace pyext {

  public class TestClass {

    public void AttachEvent(string eventName, EventHandler handler) {

      Console.WriteLine(string.Format("{0} hooked!", eventName));

    }

  }



  public static class TestClassExtension {

    [System.Runtime.CompilerServices.SpecialNameAttribute]

    public static object GetBoundMember(TestClass obj, string name) {

      return new MyEvent(obj, name);

    }

  }



  public class MyEvent {

    private readonly TestClass _obj;

    private readonly string _event;



    internal MyEvent(TestClass obj, string eventStr) {

      _obj = obj;

      _event = eventStr;

    }



    [System.Runtime.CompilerServices.SpecialNameAttribute]

    public object op_AdditionAssignment(EventHandler func) {

      _obj.AttachEvent(_event, func);

      return null;

    }

  }

}
_______________________________________________
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to