简体   繁体   English

静态类C#中的惰性属性初始化

[英]Lazy Property Initialization in static class C#

I have been given this code 我得到了这个代码

public static class Logger
{
    public static Func<ILogger> LoggerFactory;
    private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(LoggerFactory);

    public static ILogger Instance
    {
        get
        {
            return _log.Value;
        }
        public static ILogger ConfigureLogging(string AppName, Version AppVersion)
        {
             // stuff
        }
    }
}

This static class is used in the application: 该静态类在应用程序中使用:

Logger.LoggerFactory = () => Logger.ConfigureLogging(AppName, AppVersion);
Logger.Instance.Information("Starting application");

I would expect the first row to set the LoggerFactory; 我希望第一行设置LoggerFactory; however on the first attempt of writing to the log, an exception has thrown because the static Func LoggerFactory hasn't been set yet. 但是,第一次尝试写入日志时,由于尚未设置静态Func LoggerFactory,因此引发了异常。

What's wrong with this code? 此代码有什么问题?

Thanks 谢谢

The quick and dirty fix for this would be to do this: 快速而肮脏的解决方法是:

private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(() => LoggerFactory());

Lazy takes a function that will be executed when you first try to access the Value , but in your code you are passing it null because you haven't yet initialized LoggerFactory . Lazy接受了一个函数,该函数将在您首次尝试访问Value时执行,但是在您的代码中您将其传递为null因为尚未初始化LoggerFactory The static initializer in your class will run before the first time any of the static fields are accessed, so your attempt to access LoggerFactory will trigger your _log field to initialize (if it hasn't already) at which point LoggerFactory is null. 类中的静态初始化程序将在第一次访问任何静态字段之前运行,因此您尝试访问LoggerFactory的尝试将触发_log字段进行初始化(如果尚未初始化),此时LoggerFactory为null。 See, for example, here for some discussion on static initialization. 例如,请参见此处,以获取有关静态初始化的一些讨论。

You can defer accessing LoggerFactory but wrapping it in a function. 您可以推迟访问LoggerFactory但将其包装在函数中。

Here is the execution order: 这是执行顺序:

private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(null);
//LoggerFactory is null at this point

Logger.LoggerFactory = () => Logger.ConfigureLogging(AppName, AppVersion);
Logger.Instance.Information("Starting application");

and thus _log will stay as null 因此_log将保持为null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM