7

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?

Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222

3 Answers3

5

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
  • 868,454
  • 176
  • 1,908
  • 1,964
4

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
  • 77,506
  • 18
  • 119
  • 157
0

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
  • 47,787
  • 16
  • 124
  • 167