Re: Cocoa et al as HCI usability problem
Re: Cocoa et al as HCI usability problem
- Subject: Re: Cocoa et al as HCI usability problem
- From: Peter Duniho <email@hidden>
- Date: Mon, 19 May 2008 12:08:14 -0700
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 (email@hidden)
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:
This email sent to email@hidden