Tigraine

Daniel Hoelbling-Inzko talks about programming

Static members in generic classes

Posted by Daniel Hölbling on March 23, 2009

I have been using generics quite heavily lately for writing decorators to Repository classes that do logging and caching on top of the repository (I’ll talk about that another time).

Since I implemented an asynchronous cache clear method I immediately ran into some troubles with shared resources like the DB connection and so I figured the whole problem would be solved with a simple lock around the cache fill.

public class Cache<T>
{
    private static readonly object locker = new object();
    public IList<T> GetAll()
    {
        lock(locker)
        {
            //Query the DB etc.. 
            return null;
        }
    }
}

Maybe you already see the problem, but I for sure didn’t. And so it was quite a bit amazed when I discovered that the locking problem didn’t go away just like that.

Turns out, every generic class has it’s own static members. So Cache<string> has a different locker object than Cache<long> would have. Here’s the test to show this:

public class Test<T>
{
    public static long calls;
}

public class Tester {     [Fact]     public void Calls_DifferentGenerics_DontShareInstance()     {         Test<string>.calls = 10;         Test<long>.calls = 20;

        Assert.Equal(10, Test<string>.calls);         Assert.Equal(20, Test<long>.calls);         Assert.Equal(0, Test<int>.calls);     } }

Since all of my Cache objects are singletons (enforced through Windsor), there is little point in locking there.

I solved this by having a non generic class containing the static lock object and going on, but I have to say that this bug could have gotten a rather hard to reproduce bug.

Filed under net, programmierung
comments powered by Disqus

My Photography business

Projects

dynamic css for .NET

Archives

more