我班上有一个懒惰的属性:
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(字符串消息)中,methode是我在上面的SendEmail(MailMessage消息)方法中初始化的所有预测,null。
我该如何解决这个问题?
提前致谢。
答案 0 :(得分: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);
}
答案 1 :(得分:1)
丹尼尔的回答是正确的。只是想补充说明代码无效的原因。
每次访问SmtpClient
时,都会在原始代码中创建一个新的Lazy<ISmtpClient>
对象,然后立即使用SmtpClient.Value
进行初始化。这会在每行上为您提供一个新的ISmtpClient
对象。
你需要只构造一次Lazy<T>
对象,然后在属性的getter中返回它,就像在Daniels代码中一样。属性的类型应该是您要使用的类型(即,您不向消费者公开Lazy<T>
类型)。