rich-internet-apps

Callback interfaces in Java == delegates in .NET (a Java developer’s journey into .NET world)

After several years in Java/J2EE world, I recently started working on a .NET project. The motivation was to get to know the pros and cons of both world and leverage better ideas from each going forward.

Having used Apache Commons/Collections in Java, I longed for similar library in .NET. I am not sure if one already exists (quick google didn't turn up any result). However, considering that fact that Commons/Collections uses Callback interfaces a lot, it was clear that any such attempt would leverage .NET's "delegate" feature extensively. I couldn't resist trying to implement it myself. Here is what I ended up with.

So, in my case, I wanted CollectionUtils.collect() method, which transforms a list of object into a list of some other type of objects. This is a handy utility to unwrap/wrap an exising list into another list. So, for example, I have a List<StringWrapper> object in which each StringWrapper object is simply a wrapper around a "String" object. And let's say that I need to get a List<String> from List<StringWrapper> object.

In Java's Commons Collection I would use a call like this:

class StringWrapper {
public String a;
public StringWrapper(String a) {
this.a = a;
}
}

...
List<StringWrapper> aColl = new ArrayList<StringWrapper>();
aColl.add(new StringWrapper("x"));
aColl.add(new StringWrapper("y"));
aColl.add(new StringWrapper("z"));
List result = CollectionUtils.collect(aColl, new Transformer() {
public Object transform(Object o) {
return ((StringWrapper) o).a;
}
});

...

Here CollectionUtils.collect() would be something like (a very lame version of what is in Apache's Commons/Collection library):

class CollectionUtils {
public static <T, N> List<N> collect(List<T> list, Transformer<T,N> transformer) {
List<N> result = new ArrayList<N>();
for(T t: list) {
result.add(transformer.transform(t));
}
return result;
}
}

// Callback interface
interface Transformer<T,N> {
public N transform(T o);
}

In .NET, we could replicate this code 1-for-1 and get the same result. However, .NET's delegate keyword helps cut the fat and provides for a lean implementation as follows:

public class Collections
{
// a 'delegate' defines a method signature. Any method with same method signature can be used as callback method.
public delegate N Transformer<T,N>(T o);

// a function that takes a delegate method whose signature is declared by 'Transformer'
public static IList<N> Collect<T, N>(IList<T> originalList,
Transformer<T,N> transformer)
{
IList<N> returnList = new List<N>();
foreach (T oo in originalList)
{
returnList.Add(
transformer(oo));
}
return returnList;
}
}

Here, a delegate is like an abstract method and my concrete implementation could be like:

string transform(StringWrapper str) // this method's signature should match the delegate declaration
{
return str.a;
}

And the client call then becomes:

...
IList<string> result = Collections.Collect<StringWrapper, string>(listOfStringWrappers, transform);
...

Or I can do away with an anonymous delegate implementation as:

...
IList<string> result = Collections.Collect<StringWrapper, string>(listOfStringWrappers, delegate(StringWrapper str) { return str.a; });
...

Topics:

Leave a comment

Powered by WP Hashcash

Who is Pathfinder?

Topics

Search

WordPress

Comments about this site: info@pathf.com