No. Use delegates - more flexible, reusable, and expressible in more
languages than just J***.
--
Mickey Williams
www.DotNetExperts.com
...
int b = doStuff( 42 );
"mickey williams" <m...@codevtech.com> wrote in message
news:ut##3NEgBHA.1580@tkmsftngp04...
Your explanation is unclear to me, what I understand is that you want to call some delegate by name, that itself executes
operations, and isn't pointed at a method? Sounds like you just want a method then.
int someMethod(int a){
return a++;
}
int b = someMethod(42);
Obviously you want something more than that, or you wouldn't have posted. So, I'll give you a little Delegate101 here[1]. I hope it
helps remove some confusion people may have. No doubt it's a bit too remedial, but I figure there are a lot of people just
scratching their heads about what a delegate is and how to use it.
A delegate is (basically) a type safe method pointer. A delegate has no body for you to write code that can execute instructions.
That is what methods are for.
When you define the delegate you decide what the function signature looks like that it is going to point to, and you can point it to
any function with that same signature. That's anonymous to an extent. Where it isn't totally anonymous is that you can't create a
delegate and point it to any method no matter the signature, as you could with a C/C++ function ptr. This is what makes it type
safe.
So for your example, you can define a delegate like so:
public delegate int inOutIntDelegate (int value); //delegate names end in Delegate by convention.
What we've done so far is to just define a delegate. This is analogous to defining a struct or a class. The definition won't/can't
do anything. To get it to do something, you have to create an instance of it, just like for any class you define (excluding static
classes/methods of course).
Now, you can point that delegate at any method that takes an int and returns an int. To do otherwise wouldn't be type safe. You can
also point that delegate at multiple methods, as long as they all take an int arg and return an int. All of the methods you point it
at will be called. (This is referred to as multicasting.)
You can define any number of delegates, they can have the same signatures or different signatures. The delegate definition can be in
any namespace you have access to.
Now that you have a delegate defined, the next step is to define an instance variable of that delegate type somewhere. Doing so does
not point the delegate at any specific method. It is still a generic delegate (subject to a like method signature of course). You
can set whatever access level floats your boat for the instance variable. I'll simply make this one public.
public inOutIntDelegate delegateInstance;
The above doesn't create a new delegate. It creates a reference variable of type inOutIntDelegate, that at this time is null. Before
the delegate can be used you have to create a "new" delegate and assign it to the delegateInstance. (This is exactly the same
semantics as for any instance variable, of any type, declared this way. It is declared, but unassigned.)
Now, any code in any module that has access to this class where we've declared delegateInstance can assign this delegate to any
method it has access to that takes an int and returns an int. You just name the method in the constructor for the "new" instance. I
use the term "assign" very loosely here. What really happens is that the method gets added to the delegate's invocation list. If
your assignment is the first one, then the delegate gets created. Otherwise there is just a null instance variable hanging out.
//Example target method1
int target1 (int someInt){
return someInt++;
}
//Example target method2
int target2(int someValue){
return someValue--;
}
//create a new instance of an inOutIntDelegate and assign it to the delegateInstance variable we declared above. When somebody fires
the delegate, we want it to call our target1 method:
delegateInstance += new inOutIntDelegate(this.target1);
Notice the usage of "+=" in the statement. This is just some C# syntactic sugar. The compiler will see this and emit all the real
wiring up for us. The += is nice because it conveys that we are *adding* our new delegate to the invocation list of the delegate
instance pointed to by the delegateInstance variable. Clear as mud?
We could now switch it to call our target2 method if we desire:
//remove the ptr to target1
delegateInstance -= new inOutIntDelegate(this.target1);
//point at target2
delegateInstance += new inOutIntDelegate(this.target2);
Or, we could have both methods called if we desire that instead.
delegateInstance += new inOutIntDelegate(this.target2);
Now, when anybody fires off the delegateInstance delegate, it will call our target method(s). Firing the delegate is about as easy
as it gets. You just call it like it was a method.
int b = delegateInstance(42);
As you may have surmised, it's possible that delegateInstance was never initialized, or all members of the invocation list were
removed after it was initialized. This same issue exists for any reference variable, although a non-delegate reference would be
uninitialized by just assigning null to it. (myObject = null;) So, you should always check that the delegate isn't null before
firing it. (If it's null, it's not pointing at any function, so it's pointless to fire it anyway.)
if (null != delegateInstance)
int b = delegateInstance(42);
And that's all there is to it. Hope this helps somebody.
[1] Here's a great article by Chris Sells. Fun reading, and it shows how delegates can be used as a better replacement for interface
calls, and how events are wired up using delegates, and why it's so much stronger of a design when doing so. After my drivel, it'll
be nice for you to peruse a real author's works :-))
http://www.sellsbrothers.com/writing/default.aspx?content=delegates.htm
Keep Smilin'
Ed Stegman
"Arild Fines" <arild...@broadpark.no> wrote in message news:OlwjDeEgBHA.2004@tkmsftngp07...
def fun( funObj )
a = 42
b = funObj( a )
then the code that calls the function:
fun( lambda x: x + 1 )
The point here is that the code for the function object is declared inline
in the function call, you don't _need_ to declare the function you want to
pass as a named function. The (named function) equivalent to the above call
would be something like this:
def increment( x )
return x + 1
#...
fun( increment )
In java you often use Comparator objects for implementing collection
classes. These objects take the responsibility for sorting the objects
internally in the collection. You can do it like this:
Tree tree = new Tree( new StringComparator() );
That implies that you have created a class called StringComparator, which
implements the Comparator interface. (Similar to the Comparer interface in
.NET) However, since this class in any case would be pretty small, you will
in some cases find it just as easy to declare the class inline in the
constructor call:
Tree tree = new Tree( new Comparator()
{
public int compare( Object o1, Object o2 )
{
return ((String)o1).compareTo( o2 );
}
}
Yes, I know C# isnt a functional language, and its not Java either, but I
feel that delegates should allow a similar syntax. F.ex:
public int MyCompareDelegate( object o1, object o2 );
//...
Tree tree = new Tree( new MyCompareDelegate( int( object o1, object o2 )
{
return ((string)o1).CompareTo( (string)o2 );
} );
On a related side note - why are the .NET collections implemented using the
Comparator/Comparer design pattern when using delegates for comparison
callbacks would have served the same purpose?
"Ed Stegman" <nos...@home.com> wrote in message
news:OGv6DcKgBHA.2204@tkmsftngp04...
"Arild Fines" <arild...@broadpark.no> wrote in message
news:u7w8tbOgBHA.772@tkmsftngp04...
--
This posting is provided "AS IS" with no warranties, and confers no rights.
"Arild Fines" <arild...@broadpark.no> wrote in message
news:uKKCIxOgBHA.2320@tkmsftngp03...
> > Yes, I know C# isnt a functional language, and its not Java either, but
I
> > feel that delegates should allow a similar syntax. F.ex:
> >
> > public int MyCompareDelegate( object o1, object o2 );
> >
> > //...
> >
> > Tree tree = new Tree( new MyCompareDelegate( int( object o1, object
o2 )
> > {
> > return ((string)o1).CompareTo( (string)o2 );
> > } );
> >
I don't recall exactly, but I think this is a case where simplicity won out.
> > On a related side note - why are the .NET collections implemented using
> the
> > Comparator/Comparer design pattern when using delegates for comparison
> > callbacks would have served the same purpose?
I think delegates would have been fine for IComparer, but since you're
already using an interface for IComparable, I don't think it's bad that you
do other comparisons with IComparer (which is a fairly rare thing to do).