Creative operator overloading
This post is based on two facts about C#:
1) An operator is a method. It is a static method that receives 1 or 2 parameters, depends on the operator and returns a value.
2) The return value can be anything you want it to be. Usually the operator == returns a boolean, but it can return any other data type.
The example I will show is about searching for a value in a generic list.
The .net generic list has a method called FindIndex with the following signature:
public int FindIndex(Predicatematch);
Predicate
int indexOfUserToLookFor = usersList.FindIndex(delegate(User u) { return u.FirstName == userToLookFor.FirstName && u.LastName == userToLookFor.LastName; });
where usersList is defined as List
int indexOfUserToLookFor = usersList.FindIndex(Where.User == userToLookFor);
would be much nicer and certainly more readable.
In order to enable such syntax, the two fact about operator overloading mentioned above come to play. The code:
public class UserQuery { public static Predicate<User> operator == (UserQuery ignored, User other) { return new Predicate<User>(delegate(User u) { return u.FirstName == other.FirstName && u.LastName == other.LastName; }); } … }
does the trick. What this code means, is that when the operator == is used for object of type UserQuery (left hand side) and User (right hand side), return a Predicate
The Where in the phrase ‘Where.User == userToLookFor’ is just for nicer syntax. It is implemented simply as:
public static class Where { public static UserQuery User { get { return new User.UserQuery(); } } }
This post was inspired by the code generated using the NHibernate Query Generator which uses this technic extensively. For an example of code by the NQG look here.
The complete code example for this post can be downloaded here
Tags: c#, operator overloading