On Thu, 2005-09-22 at 23:26 +0200, Samuel Abels wrote: > On Do, 2005-09-22 at 18:45 +0200, Robert Jordan wrote: > > You're looking for something like that (untested): > > [...] > > return d.DynamicInvoke (args); > > [...] > > Thanks, I did not know this method before. I now implemented this using > a combination of this and the Mono 2.0 generics support. Also Thanks to > JD for mentioning this.
<snip icky code using BeginInvoke/> With the introduction of anonymous delegates to C# 2.0, I think we need to get more functional programmers involved. Throw in generics, and you can do some some nifty type-safe delegate chaining: // Functors with C# 2.0... using System; using System.Collections; delegate T Generator <T> (); delegate TRet Generator <TRet, TArg> (TArg arg); class FunctorGen { public static Generator<TRet> BindFirst <TRet, TArg> (Generator<TRet, TArg> gen, TArg arg) { return new Generator<TRet> ( new _FunctorInfo <TRet, TArg>(gen, arg).Invoke ); // alas, my example of using an anonymous delegate as a // generator function causes gmcs to die. :-( // because this doesn't work, we need the _FunctorInfo class. // return delegate { return gen (arg); }; } private class _FunctorInfo<TRet, TArg> { private Generator<TRet, TArg> gen; private TArg arg; internal _FunctorInfo (Generator<TRet, TArg> gen, TArg arg) { this.gen = gen; this.arg = arg; } public TRet Invoke () { return gen (arg); } } public static void Main () { Generator<void> c1 = BindFirst <void, ArrayList> (InvokeArrayList, null); Generator<void> c2 = BindFirst <void, string> (InvokeString, "hello, world"); Generator<void> c3 = BindFirst <void, string> ( delegate (string s) { InvokeString2 ("first string", s); }, "second string" ); c1 (); c2 (); c3 (); } private static void InvokeArrayList (ArrayList a) {} private static void InvokeString (String a) {Console.WriteLine (a);} private static void InvokeString2 (String a1, string a2) { Console.WriteLine (a1); Console.WriteLine (a2); } } Note that FunctorGen._FunctorInfo really shouldn't be necessary, as the commented out code in FunctorGen.BindFirst should work. Alas, it causes gmcs to vomit: ** ERROR **: file metadata.c: line 2736 (mono_type_size): assertion failed: (!gclass->inst->is_open && !gclass->klass->generic_container) aborting... Aborted No nice short generator methods for me, but it should work eventually. The real nice point is that the above can be done for *any* delegate taking 0 or 1 parameters (supporting more isn't difficult, just make more overloads of Generator and FunctorGen.Bind*), and you can pass anonymous delegates as part of the original delegate to bind (as seen in c3 for InvokeString2). All this, and completely compile-time type safe. The only downside is that it requires a 2.0 runtime to execute, but it's fun nonetheless. - Jon _______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list