12

我班上有一个懒惰的财产:

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。

我怎样才能解决这个问题?

提前致谢。

4

2 回答 2

22

你用Lazy<T>错了。

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

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);
}
于 2013-02-06T13:50:08.123 回答
1

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

每次访问SmtpClient时,在原始代码中Lazy<ISmtpClient>都会创建一个新对象,然后立即使用SmtpClient.Value. 这会ISmtpClient在每一行上为您提供一个新对象。

您只需要构造Lazy<T>一次对象,并在属性的 getter 中返回它,就像在 Daniels 代码中一样。属性的类型应该是您想要使用的类型(即您不Lazy<T>向消费者公开类型)。

于 2013-04-05T10:58:45.550 回答