views:

140

answers:

3

I have the following code:

private static LogLevel? _logLevel = null;

public static LogLevel LogLevel
{
    get
    {
        if (!_logLevel.HasValue)
        {
            _logLevel = readLogLevelFromFile();
        }

        return _logLevel.Value;
    }
}

private static LogLevel readLogLevelFromFile() { ... }

I get a ReSharper warning on the return statement about a possible System.InvalidOperationException and it suggests I check _logLevel to see if it is null first. However, readLogLevelFromFile returns LogLevel, not LogLevel?, so there is no way the return statement could be reached when _logLevel is null. Is this just an oversight by ReSharper, or am I missing something?

+4  A: 

That looks like a bug in Resharper.

Note, however, that that isn't thread-safe.

The best way to do this is to use a static initializer, like this:

public static LogLevel Instance { get { return Nested.level; } }

class Nested {
    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Nested() { }

    internal static readonly LogLevel level = readLogLevelFromFile();
}
SLaks
that'll change when its instantiated + load it if its not used at all
eglasius
`Cannot resolve symbol 'Instance'`. Did you mean to do a `new Nested()` there?
Sarah Vessels
@Sarah: I meant `.level`. It should work now.
SLaks
+3  A: 

You could refactor it into something like this:

return (_logLevel = _logLevel ?? readLogLevelFromFile()).Value;

Alternatively you can use the built in lazy type (Requires .NET 4.0 or you can roll your own.):

public static LogLevel LogLevel
{
    get { return _logLevel.Value; }
}
private static Lazy<LogLevel> _logLevel = new Lazy<LogLevel>(readLogLevelFromFile);
ChaosPandion
That actually gives the compiler error `Cannot implicitly convert type 'MyNS.LogLevel?' to 'MyNS.LogLevel'. An explicit conversion exists (are you missing a cast?)`.
Sarah Vessels
@Sarah - Opps, I forgot the call to `Value`.
ChaosPandion
That's even more compact than what I have; thanks!
Sarah Vessels
A: 

Resharper wasn't 'smart' enough to figure it out for you. It is kind of a complex thing to figure out, I would imagine.

I prefer @ChaosPandion's refactoring anyways...

Brian Genisio