Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Anonymous delegates?

0 views
Skip to first unread message

Arild Fines

unread,
Dec 8, 2001, 5:08:35 PM12/8/01
to
Is there any syntax in C# for declaring anonymous delegates? Eg, something
similar to anonymous inner classes in Java or lambda functions in various
other languages.
If not, what is the rationale for omitting them?


mickey williams

unread,
Dec 8, 2001, 7:02:38 PM12/8/01
to

"Arild Fines" <arild...@broadpark.no> wrote in message
news:upbziQDgBHA.1320@tkmsftngp05...

No. Use delegates - more flexible, reusable, and expressible in more
languages than just J***.

--
Mickey Williams
www.DotNetExperts.com


Arild Fines

unread,
Dec 8, 2001, 7:27:18 PM12/8/01
to
That was sort of what I was asking - a way to use delegates without
explicitly naming a method.
Something like this:
MyDelegate doStuff = new MyDelegate( int( int a )
{
//...
} );

...
int b = doStuff( 42 );

"mickey williams" <m...@codevtech.com> wrote in message
news:ut##3NEgBHA.1580@tkmsftngp04...

Ed Stegman

unread,
Dec 9, 2001, 6:45:38 AM12/9/01
to
I'm not a Java guy, so I don't know what anonymous inner classes are. Not sure I follow you on what you are asking for. Perhaps you
could explain the problem your problem domain? Although C# looks a lot like Java, it isn't Java. You'll need to approach things a
bit differently. Java looks a lot like C++ (minus some ptrs.) Yet you wouldn't consider approaching things the same way. This
doesn't make one better than the other, just different. :-))

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...

Arild Fines

unread,
Dec 9, 2001, 2:28:24 PM12/9/01
to
Hmm... I dont think either of you really understood the question - I guess I
should have phrased it better. My problem isnt with the delegate syntax(to
the degree that actually is a problem, I can always look it up). Nor is this
a Java vs C# thing(I'm not really a Java guy either), I only used Java's
anonymous inner classes as an example of what I was after.
Functional languages lets you pass functions as arguments to other
functions. Furthermore, they sometime allow the function definition to be
defined inline in the function call.
Here's a Python example.
You have a function taking a function object:

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

unread,
Dec 9, 2001, 3:06:42 PM12/9/01
to
The line

public int MyCompareDelegate( object o1, object o2 );
should of course be
public delegate int MyCompareDelegate( object o1, object o2 );

"Arild Fines" <arild...@broadpark.no> wrote in message

news:u7w8tbOgBHA.772@tkmsftngp04...

Eric Gunnerson

unread,
Dec 10, 2001, 11:51:43 AM12/10/01
to
Comments Inline

--
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).


0 new messages