У меня есть следующий код:
private static LogLevel? _logLevel = null;
public static LogLevel LogLevel
{
get
{
if (!_logLevel.HasValue)
{
_logLevel = readLogLevelFromFile();
}
return _logLevel.Value;
}
}
private static LogLevel readLogLevelFromFile() { ... }
Я надеваю ReSharper, предупреждающий return
оператор о возможном System.InvalidOperationException
и это предлагает, чтобы я проверил _logLevel
видеть, ли это null
сначала. Однако readLogLevelFromFile
возвраты LogLevel
, нет LogLevel?
, таким образом, нет никакого пути return
оператор мог быть достигнут когда _logLevel
null
. Это - просто контроль ReSharper, или я пропускаю что-то?
Это похоже на ошибку в Resharper.
Заметьте, однако, что это не потокобезопасно.
Лучший способ сделать это - использовать статический инициализатор, например, такой:
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();
}
Resharper не был достаточно «умен», чтобы понять это за вас. Я полагаю, это довольно сложная вещь, которую нужно понять.
Я в любом случае предпочитаю рефакторинг @ ChaosPandion ...
Вы можете реорганизовать его примерно так:
return (_logLevel = _logLevel ?? readLogLevelFromFile()).Value;
В качестве альтернативы вы можете использовать встроенный ленивый тип (требуется .NET 4.0 или вы можете использовать свой собственный .):
public static LogLevel LogLevel
{
get { return _logLevel.Value; }
}
private static Lazy<LogLevel> _logLevel = new Lazy<LogLevel>(readLogLevelFromFile);