We are a user experience design and software development firm
Hire us to design your site, build your application, serve billions of users and solve real problems.
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: Web/Tech
Hire us to design your site, build your application, serve billions of users and solve real problems.