繁体   English   中英

获取访问器返回新实例是否是错误的做法?

[英]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.

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