On May 19, 2008, at 11:21 AM, Greg Titus wrote:

[...]
I've worked in Java quite a bit in the past, and I disagree, but more to the point: I've never done significant work in C# before, so if that's an environment you are familiar with and you are willing, I'd very much like to see what prepareWithInvocationTarget: would look like in that language.

First, I'll address some other observations about the code I posted: yes, I was simply showing what the equivalent syntax would be. .NET doesn't have an NSUndoManager per se, with identical semantics to Cocoa's. Without a clear question, I really didn't know what it was Michael was proposing I write so I answered as best I could at the time.

And yes, for it to work exactly as I wrote my response, in C# you would have to have your NSUndoManager compiled for a specific class, so that it had the appropriate overloads for how it would be used.

However, _with_ reflection we can do much of the same kinds of things that Obj-C does, without knowing in advance the classes that might use the NSUndoManager class.

One advantage I see in Cocoa is that, because classes may respond to selectors that they didn't even declare, NSUndoManager can simply set a temporary variable, and then catch a selector to be saved away for later invocation. This makes the reflection aspect ("introspection" in Objective-C) more transparent.

An approach in C# that is still reasonably close to the Obj-C version would be to instead pass a method name and an array of arguments (so, the syntax isn't identical, but comparable):

undoManager.prepareWithInvocationTarget(this, "setColor", object [] { mColor });

Then the method would look something like this (warning: email code, uncompiled, untested):

void prepareWithInvocationTarget(object target, string name, object[] args)
    {
        Type[] argTypes = new Type[args.Length];
        MethodInfo targetMethod;

        for (int iarg = 0; iarg < args.Length; iarg++)
        {
            argTypes[iarg] = args[iarg].GetType();
        }

        targetMethod = target.GetType().GetMethod(name, argTypes);

// save targetMethod and args in an appropriate data structure for
        // later retrieval and invocation
        // ...code omitted for brevity
    }

In reality, I would (and have) more likely implement an undo manager that uses anonymous methods. Then all you're saving to your undo state is a delegate that does what you want (assumes the "property" semantic I posted):

    undoManager.AddUndo(delegate { color = mColor; });

This is more idiomatic in C# and wouldn't need all that messy reflection stuff. Executing the undo is a simple matter of invoking the delegate that was passed, a simple one-line operation that reads like a method call (note that the use of the name "delegate" is very different in C# than in Cocoa...C# "delegate" is more like a function pointer than an actual object to which some selector has been delegated).

I don't understand the comments saying that you can't do something similar in Java. Java has the same kind of reflection features that C# has. The anonymous method approach wouldn't work, as Java doesn't have anything equivalent to C# delegates, but Java does have interfaces and using those with anonymous types in lieu of anonymous methods is a common Java idiom that works well.

Pete
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to