【问题标题】:C# Lazy propertyC# 惰性属性
【发布时间】:2013-02-06 13:47:18
【问题描述】:

我的班级中有一个 Lazy 属性:

private Lazy<ISmtpClient> SmtpClient
    {
        get
        {
            return new Lazy<ISmtpClient>(() => _objectCreator.Create<ISmtpClient>(), true);
        }
    }

也是使用此属性的方法:

public void SendEmail(MailMessage message)
    {
        SmtpClient.Value.ServerName = "testServer";
        SmtpClient.Value.Port = 25;

        SmtpClient.Value.Send(message);
    }

但是在我的 SmtpClient 中,在 Send(string message) 方法中是我在上述 SendEmail(MailMessage message) 方法中初始化的所有属性,null。

我该如何解决这个问题?

提前致谢。

【问题讨论】:

    标签: c#-4.0


    【解决方案1】:

    你用错了Lazy&lt;T&gt;

    使用Lazy&lt;T&gt; 时,您会公开一个实际类型的属性,并且您有一个Lazy&lt;T&gt; 实例。您不会在每次访问该属性时都创建一个新的:

    Lazy<ISmtpClient> _smtpClient =
        new Lazy<ISmtpClient>(() => _objectCreator.Create<MySmtpClient>(), true);
    
    private ISmtpClient SmtpClient
    {
        get
        {
            return _smtpClient.Value;
        }
    }
    

    现在,第一次访问 SmtpClient 属性时,对象创建者会创建一个新的 MySmtpClient 实例。这是返回的。在后续调用中,返回相同的实例。

    用法如下:

    public void SendEmail(MailMessage message)
    {
        SmtpClient.ServerName = "testServer";
        SmtpClient.Port = 25;
    
        SmtpClient.Send(message);
    }
    

    【讨论】:

    • 谢谢,但是我确实发布了惰性属性的错误代码,实际代码是这样的: private Lazy SmtpClient { get { return new Lazy(() => _objectCreator .Create(), true); } } 还是不好?
    • @Djave:这和你之前的完全一样。
    • 区别是 _objectCreator.Create() ,而不是 _objectCreator.Create()
    • @Djave:啊。不会改变我在回答中解释的根本问题。
    • @Djave:这是不可能的。请再次检查。
    【解决方案2】:

    丹尼尔的回答是正确的。只是想澄清一下为什么您的代码不起作用。

    每次访问SmtpClient,在您的原始代码中,都会创建一个新的Lazy&lt;ISmtpClient&gt; 对象,然后立即使用SmtpClient.Value 对其进行初始化。这会在每一行上为您提供一个新的 ISmtpClient 对象。

    您只需要构造一次Lazy&lt;T&gt; 对象,并在属性的getter 中返回它,就像在丹尼尔斯代码中一样。属性的类型应该是您要使用的类型(即您不向消费者公开 Lazy&lt;T&gt; 类型)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-19
      • 1970-01-01
      • 2014-09-02
      • 2021-02-08
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多