musium musium - 2 months ago 7
C# Question

R# - Possible incorrect implementation of Double-Check Locking pattern

private readonly Object _syncRoot = new Object();
public IdGenerator ClientIdGenerator
{
get
{
if ( clientIdGenerator != null )
return clientIdGenerator;

lock ( _syncRoot )
{
if ( clientIdGenerator != null )
return clientIdGenerator;

return clientIdGenerator = ClientIdPrefix != null ? new IdGenerator( ClientIdPrefix ) : new IdGenerator();
}
}
}


R# displays a warning "Possible incorrect implementation of Double-Check Locking pattern. Read access to checked field" on the line creating the instance of IdGenerator.

R# does not display the warning after I changed the code to this:

public IdGenerator ClientIdGenerator
{
get
{
if ( clientIdGenerator == null )
lock ( _syncRoot )
{
if ( clientIdGenerator != null )
return clientIdGenerator;

clientIdGenerator = ClientIdPrefix != null ? new IdGenerator( ClientIdPrefix ) : new IdGenerator();
}
return clientIdGenerator;
}
}


Is anything wrong with the first example, or is R# displaying a "wrong" warning?

Answer

Your first version should work nicely, but just to avoid misunderstandings for part of code analysis engines or co-worker, you can use the standard pattern:

private readonly Object _syncRoot = new Object();
public IdGenerator ClientIdGenerator
{
    get
    {
        if (clientIdGenerator == null)
        {
            lock (_syncRoot)
            {
                if (clientIdGenerator == null)
                {
                    clientIdGenerator = ClientIdPrefix != null ? new IdGenerator(ClientIdPrefix) : new IdGenerator();
                }
            }
        }

        return clientIdGenerator;
    }
}

This way you make clear your intentions.

Comments