Tonight at JGO: Java vs C# vs C++ vs X

1. Round: function pointers vs. delegates vs. anonymous classes

C++ functions are knocked out by the first hit, since class methods can’t be ones, and they are unsafe :wink:

C# delegates seem to have good foot work, they are easy to use,


// definition
delegate void Foo(object arg);

// implementation
Object anObject = ..;

Foo foo = delegate(object arg) {
    Console.WriteLine(arg.ToString() + anObject);
};

// calling
foo("Hello");

but there comes Java, leaves its defense and hits back with it’s anonymous classes, which are even more powerfull , beeing object oriented by encapsulating data:


// definition
interface Delegates {
 void foo(Object arg);
 void bar(); // yeah not only one function
}

// implementation
final Object anObject = ..;

Delegates delegates = new Delegates() {
  public void foo(Object arg) {
      System.out.printLine(arg.ToString() + anObject);
  }
   public void bar() {
      System.out.printLine("Bar");
   }
};

// calling
delegates.foo("Hello");
delegates.bar();

so far a slightly advantage for Java. But wait, there comes X - the underdog, which is exactly like using Java’s anomymous methods, but has a nice syntax sugar for interfaces with only a single method:


// definition
interface Delegate {
 void foo(Object arg);
}

// implementation
final Object anObject = ..;

Delegates delegate = new Delegate.foo(Object arg) { // the single method, right behind the interface name
      System.out.printLine(arg.ToString() + anObject);
};

// calling
delegate.foo("Hello");

nice, isn’t it :wink:

to be continued :stuck_out_tongue:

one advantage delegates have though is executing several methods in one call.

e.g.:


delegate void Foo(string s);
class Test {
	public Test() {
		Foo f = null;
		f += new Foo(method1);
		f += new Foo(method2);
		f += new Foo(method3);
		f += new Foo(method4);
		f("bar"); // executes all 4 methods
		f -= new Foo(method3);
		f("bar"); // executes all methods except method3
	}
	protected void method1(string s) { /* whatever */ }
	protected void method2(string s) { /* whatever */ }
	protected void method3(string s) { /* whatever */ }
	protected void method4(string s) { /* whatever */ }
	static void Main(string[] args) { new Test(); }
}

pretty handy in some situations… oO;

p.s. I’m just playing devil’s advocate here. I’ve been doing Java for 8 years but I gotta admit I really enjoy C# also :slight_smile:

edit: oops, forgot you cant captilize “String” in C# ::slight_smile:

It’s some time ago, but I’ve programmed c# for two years and I’m very sure you can’t do this! You’ll need an event-object, which can collect delegates of the same type, s.th.


delegate void Foo(string s);

public event Foo FooEvent;

FooEvent += new Foo(method);


Do you know what the default implementation of an event-object is? It’s similiar like ‘Set’ of Java’s EvenListeners. Of course ‘+=’ is shorter in syntax than addXXXListener, but as you know in Java a listener interface can have more methods, so one addWindowListener is equivalent to more c# events (Form’s Close, Closing, …) and if you want to override only a single method, use the WidnowAdapter class.

but thanls for the hint, I’m concerning ‘Event Handling’ as another round in this bare-knuckle fight :slight_smile:

I program C# reguarly, you can indeed do this :wink: the process I showed you is not limited to ‘event’ types, it is the main purpose of delegates.

go ahead, run this code: (.NET 2.0)


using System;
delegate void Foo(string s);
class Test {
	static void Main(string[] args) {
		new Test();
	}
	public Test() {
		Foo f = null;
		f += new Foo(method1);
		f += new Foo(method2);
		f += new Foo(method3);
		f += new Foo(method4);
		f("bar"); // executes all 4 methods
		Console.WriteLine("");
		Console.WriteLine("removing method3 ...");
		Console.WriteLine("");
		f -= new Foo(method3);
		f("bar"); // executes all methods except method3
		Console.ReadKey();
	}
	protected void method1(string s) {
		Console.WriteLine("method1: "+s);
	}
	protected void method2(string s) {
		Console.WriteLine("method2: "+s);
	}
	protected void method3(string s) {
		Console.WriteLine("method3: "+s);
	}
	protected void method4(string s) {
		Console.WriteLine("method4: "+s);
	}
}

output:

woaaah, guess this was kind of a shadow kick :wink:

didn’t know that, altough I’ve worked with c# 2.0 beta most the times… since i’m currently on linux, i cannot test your code but i believe you that it runs well… btw. can you tell me how to overload the +=/-= operators for a delegate, I have in mind how to do this for an event object but for delegates no idea - thanks :slight_smile:
Oh, and another point, is how the default implementation looks, are the delegates stored in a list like for events?

I dont believe you can overload those operators on a delegate since it’s considered a primitive (such as int and byte etc). the only way you might can do it is if the return type of delegate overloads it. e.g:


delegate Something Foo(String s);

if the Something class overloads the += operator, that might be enough to do it. shrug I will look into it. sort of pointless in this topic since Java offers no operator overloading :slight_smile:

I would suppose the delegates use a list of some sort since you can add/remove methods to one delegate. By the way, you can add any method to a delegate provided the method shares the same signature as the delegate (e.g. returntype and parameters).

Events in C# seem to be just specialized delegates. But with further experience I may prove myself wrong :slight_smile:

edit:
one advantage event-wise in C# is that 99% of the time you dont even have to worry about event listeners (er, well, “callbacks” would be a more precise term). For example, the System.Windows.Forms class pre-defines every method for every event that could possibly happen to that window. there’s no need to add any listeners, just override an event method that you need to use :wink:

I was just to curious, so I did some research:

Combining delegates, create an instance of System.MulticastDelegate, which has a linked list of delegates, called an invocation list, consisting of one or more elements. Actually not much difference of an event I guess. well on the one hand its nice syntax sugar again. on the other however, having a null initialized object at a given line and using it in the next one on the right side of the expression (a += b implies a = a+ b) really makes my eyes bleed:


..
Foo f = null;
f += new Foo(method1);
..

ah, that’s only because it’s fairly new syntax :wink:

null+something isn’t really a bad thing. just like 0+1 isnt 0 :slight_smile: