Reshef’s tip of the day

.net development tips

Archive for the ‘operator overloading’ Category

Implicit construction of objects

Thursday, January 3rd, 2008

An hidden and not commonly used feature of C# is the implicit constructor. It is so uncommon to see it, that one time (in band camp), when I saw it being used, it took me a while to understand what is going on…

Actually, implicit construction is not a real feature by itself, but rather a by-product of implicit conversion between datatypes. Look here for more information about implicit conversions.

Anyway, what it means, is that the object is being constructed by an invisible factory method.

Take a look at this options to instantiate an object:

Telephone tel = new Telephone("972542221234"); // By Ctor

Telephone tel = Telephone.New("972542221234"); // Factory method

Telephone tel = "972542221234"; // Implicit Ctor

Here is the implementation of the telephone object I used for this example. The implicit constructor implementation is bolded:

public class Telephone
{
    private readonly int countryCode;
    private readonly int areaCode;
    private readonly long phoneNumber;

    public Telephone(string phoneNumber)
    {
        // Dummy logic just for this example
        this.countryCode =
            Convert.ToInt32(phoneNumber.Substring(0, 3));

        this.areaCode =
            Convert.ToInt32(phoneNumber.Substring(3, 2));

        this.phoneNumber =
            Convert.ToInt64(phoneNumber.Substring(5));
    }

    public int CountryCode
    {
        get { return countryCode; }
    }

    public int AreaCode
    {
        get { return areaCode; }
    }

    public long PhoneNumber
    {
        get { return phoneNumber; }
    }

    public static Telephone New(string phoneNumber)
    {
        return new Telephone(phoneNumber);
    }

    public static implicit operator Telephone(string phoneNumber)
    {
        return Telephone.New(phoneNumber);
    }
}

This kind of syntax can help having less verbose code, and in software, less is usually more.

Creative operator overloading

Monday, December 3rd, 2007

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(Predicate match);

Predicate is a delegate that receives a parameter of type T for evaluation and returns a boolean in case the that there is a match according to the logic defined by the predicate. This works like This:

int indexOfUserToLookFor = usersList.FindIndex(delegate(User u)
{
    return u.FirstName == userToLookFor.FirstName &&
        u.LastName == userToLookFor.LastName;
});

where usersList is defined as List and User is a class. The code above is not so elegant or readable. Having something like:

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 that contains the logic to match a user. Pay attention that the UserQuery parameter is named ignored since it is indeed, ignored. The predicate that is returned is the same as the predicate in the first FindIndex snippet therefore the functionality is the same.

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

Jajah is the VoIP player that brought you web-activated telephony.