Extension methods have been around for a while in C# by now, and sometimes you see questions regarding the real use of this approach. That can be debated, and this text is not aiming to cover the subject in whole, but instead show on one case where you may find them usable.

Recently I was working on a piece of code that needed a lot of synchronization to control access to a shared resource (that code will be covered in a coming blog post). I used the ReaderWriterLockSlim for this, which sometimes produced code blocks like the following (this code sample has, as usual, been created just for demo purposes):

private static int GetFromQueueWithoutExtensions()
{
    int result = -1;
    _lock.EnterUpgradeableReadLock();
    try
    {
        if (_sharedResource.Count > 0)
        {
            _lock.EnterWriteLock();
            try
            {
                result = _sharedResource.Dequeue();
            }
            finally
            {
                _lock.ExitWriteLock();
            }
        }
    }
    finally
    {
        _lock.ExitUpgradeableReadLock();
    }

    return result;
}

_sharedResource is a static Queue<int> instance, declared elsewhere in the class. The above method contains 12 lines of code (disregarding blank lines, and lines consisting of only a curly brace). In these 12 lines of code, only 4 are directly related to the task of the function, the remaining 8 lines being what we could call infrastructure; various control mechanisms to make sure that appropriate locks are acquired and released. This can make the code harder to read, since you will need to filter out the (minority of) lines that carry out the actual functionality of the method.

If we investigate the code structure a bit closer, we can see that the pattern around running code while holding a certain lock looks like this (pseudo code):

acquire the lock
try
{
   execute the task while holding the lock
}
finally
{
   release the lock
}

This is a repeating pattern, so now I see two reasons to refactor the original code sample shown above; try to move infrastructure out of the method, and stick to the DRY (Don't Repeat Yourself) principle.

I will start by trying to encapsulate the "run code under lock" pattern into a separate method:

private static void RunWithUpgradeableReadLock(ReaderWriterLockSlim readerWriterLock, Action action)
{
    readerWriterLock.EnterUpgradeableReadLock();
    try
    {
        action();
    }
    finally
    {
        readerWriterLock.ExitUpgradeableReadLock();
    }
}

The above code needs to be repeated for each lock method (so methods encapsulating EnterReadLock and EnterWriteLock need to be added). Now, the calling code can be shortened down quite considerably:

private static int GetFromQueueWithEncapsulation()
{
    int result = -1;

    RunWithUpgradeableReadLock(_lock, () =>
    {
        if (_sharedResource.Count > 0)
        {
            RunWithWriteLock(_lock, () =>
            {
                result = _sharedResource.Dequeue();
            });
        }
    });

    return result;
}

Now, by making a couple of small modifications to the encapsulating method, we can make it into an extension method. First we need to move it into a class that is declared as public static. Second we need to add the keyword this in front of the ReaderWriterLockSlim parameter:

public static class ReaderWriterLockSlimExtensions
{
    public static void RunWithUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLock, Action action)
    {
        readerWriterLock.EnterUpgradeableReadLock();
        try
        {
            action();
        }
        finally
        {
            readerWriterLock.ExitUpgradeableReadLock();
        }

    }
}

By doing this you add one feature above all (in my opinion): discoverability. The method RunWithUpgradeableReadLock method will show up in IntelliSense when using a ReaderWriterLockSlim:

extensionmethods.intellisense

In order to have your code call the extension method rather than the encapsulated method shown earlier, you write code that invokes the method on the lock object rather than passing the lock object as an argument:

private static int GetFromQueueWithExtensions()
{
    int result = -1;

    _lock.RunWithUpgradeableReadLock(() =>
    {
        if (_sharedResource.Count > 0)
        {
            _lock.RunWithWriteLock(() =>
            {
                result = _sharedResource.Dequeue();
            });
        }
    });

    return result;
}

This code block contains two extra lines of code (plus scoping curly braces) for the locking mechanisms. In my opinion this is making the code much more to the point, making it easier to read and understand what it does.

kick it on DotNetKicks.com

Bookmark and Share

When designing a type (I use the term type rather than class since the discussion here could just as well be applied to value types) they will typically use a field to store state internally. When exposing the state to consumers of the type, you can choose to do so by either making the field itself public or by creating a property through which the field is exposed. There is a third choice as well and that is to create methods that will get or set the value, but I will leave that out of the discussion for now (after all, this is what happens technically when exposing a field through a property).

public class SomeClass
{
    public int SomeValue;
}

The type above is about as simple as it gets. A class exposing a public field. Access to this field will be highly efficient since there is no extra wrapping around it; it is the field itself that is exposed. However, this is often not considered to be a good idea. There are several reasons for this. I will discuss some of them here.

Let's say that we release a class library with the above type in it, allowing others to use it in their code. Later we realize that we need to restrict the possible values that may be assigned to SomeValue. In fact, for some reason the value 42 is not acceptable. In order to enforce this restriction, we change our code so that SomeValue is now a property instead:

public class SomeClass
{
    private int _someValue;
    public int SomeValue
    {
        get { return _someValue; }
        set
        {
            if (value == 42)
            {
                throw new ArgumentException("value must be 42");
            }
            _someValue = value;
        }
    }
}

Bang! We just broke all code that is compiled against our type. Any code using your type must now be recompiled. This is perhaps the strongest argument against exposing fields directly; future-proofing. By wrapping field access into a property, you have created a platform where you can add validation without breaking any consuming code. This is a good thing to do, because we cannot see into the future. We have no idea how business requirements may change next month.

But wait, there is more. Do you use data binding? (I try to stay away from it, but that is just me). If you do, you may want to make sure that your types are data bindable. Currently, data binding works with properties, but not fields. If you choose to expose the field directly, you also choose not to support data binding.

Another nice feature that you get when exposing state through properties is that you can have different access levels on get and set operations:

public class SomeClass
{
    private int _someValue;
    public int SomeValue
    {
        get { return _someValue; }
        protected set
        {
            if (value == 42)
            {
                throw new ArgumentException("value must be 42");
            }
            _someValue = value;
        }
    }
}

Now SomeValue is designed so that any code can get the value, but only code in the SomeType class or any descendant class can set it. This kind of granularity of access control is not available with fields.

Given the arguments above, I would say that it is a good idea to default to exposing values through properties, unless there are very strong reasons not to. Then what about the internal code in the type itself? Should that code be allowed to use the field directly?

My personal, strong opinion is no, also the internal code should use the property (again, unless there are strong reasons not to). The main reason for this is what we can call debuggability: if you assign the value to the field in one, and only one place, you can easily track down what piece of code that is every now and then assigning that weird value that screws up the state of your program. Just set a breakpoint (or write to the log) in the property setter and wait for the offending code to make the call, then examine the stack trace. If you allow code to set the value in the field directly, this operation will be a lot more complicated.

I have stated that you should use the property unless there are strong reasons not to. What exactly do I consider strong reasons. Naturally, that depends on your code and what it does, but one example may be performance: if performance is very crucial, direct field access may be preferable. However: never optimize code for performance until you have measured it. Really. I cannot recall that I have ever come across a real-world case where this performance difference was an issue in any project that I have worked with.

Conclusion

I like to think about the property as a contract and the field as implementation. Any piece of code that needs to get or set the value should use the contract. Relying on the implementation should be done only when it is really needed.

kick it on DotNetKicks.com

Bookmark and Share

Say you have a string with a file name with a relative path, such as “..\..\somedir\somefile.txt”, and you want to resolve the full path to the file given a certain reference point in the file system, how would you go about to solve that. Turns out it is rather simple: System.Uri has relative path resolving powers:

public static string ResolveRelativePath(string referencePath, string relativePath) 
{ 
    Uri uri = new Uri(Path.Combine(referencePath, relativePath)); 
    return Path.GetFullPath(uri.AbsolutePath); 
}

Now you can resolve the path like this:

// path will contain "c:\directory\anothersubdir\somefile.txt"
string path = ResolveRelativePath(@"c:\directory\subdir", @"..\anothersubdir\somefile.txt");

Update: As Morgan points out in the comments, using System.Uri is actually not necessary. The following code will do the same job (but in a more efficient manner):

public static string ResolveRelativePath(string referencePath, string relativePath) 
{ 
    return Path.GetFullPath(Path.Combine(referencePath, relativePath));
}

I shall spend a moment in the corner of shame for not doing that from the start.

kick it on DotNetKicks.com

Bookmark and Share