![](/img/trans.png)
[英]Is it bad practice to wrap a new SqlConnection instance in a static method?
[英]Is it bad practice for get accessor to return a new instance?
从访问器返回新实例是否存在问题? 如果是这样,是否有更好的方法?
public class Person
{
private RecIpDet _ipDet;
public RecIpDet IpDet
{
get
{
if(_ipDet == null)
_ipDet = new RecIpDet();
return _ipDet;
}
}
}
存在问题,因为您从未设置字段,所以每次调用该属性时都会返回一个新对象。
如果_ipDet
为空,则应设置它,然后将其返回。 这称为延迟实例化或延迟初始化 。
public class Person
{
private RecIpDet _ipDet;
public RecIpDet IpDet
{
get
{
if (_ipDet == null)
{
_ipDet = new RecIpDet();
}
return _ipDet;
}
}
}
请记住,这不是线程安全的,因此,如果这对您来说是一个因素,那么您将需要一个更强大的机制。 对于单线程应用程序,这种延迟实例化方法很好。
如果您使用的是.NET 4.0或更高版本,则可以使用Lazy<T>
类,我认为它是线程安全的:
public class Person
{
private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>(() => new RecIpDet());
public RecIpDet IpDet
{
get
{
return _ipDet.Value;
}
}
}
对我们来说,通常的做法是使用:
get
{
return _ipDet ?? (_ipDet = new RecIpDet());
}
根据您的评论,您似乎确实要设置实例,因此,这是一个经典的惰性实例化示例,很好(尽管不是线程安全的)。 如果您不必担心线程安全,那么这绝对可以解决:
get
{
if (_ipDet == null)
_ipDet = new RecIpDet();
return _ipDet
}
但是,如果您使用的是.NET 4.0,我建议您使用Lazy<T>
而不是构建自己的惰性构造:
public class Person
{
private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>();
public RecIpDet IpDet
{
get { return _ipDet.Value; }
}
}
Lazy的Value会在第一次调用时调用该类型的构造函数,并且也是线程安全(可以选择不同)级别的线程安全。
到目前为止,您将始终返回一个新对象。 除非以某种方式将_ipDet设置为一个值。 这使您的代码的行为非常不可预测。 实现单例模式并替换返回新的RecIpDet();。 与_ipDet = new RecIpDet(); 或者使它始终返回一个新对象,这很好。
使用惰性实例化是很不寻常的,大多数情况下,它是用于Singleton模式的,在这里您将找到有关此的更多信息:
在此页面中,您甚至可以找到使其成为线程安全的方法。
对于可以从应用程序中的任何位置访问的全局对象而言,它非常有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.