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

Reply via email to