Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# get访问器返回新实例是一种不好的做法吗?_C# - Fatal编程技术网

C# get访问器返回新实例是一种不好的做法吗?

C# get访问器返回新实例是一种不好的做法吗?,c#,C#,从访问器返回新实例是否存在问题?如果是,有没有更好的方法 public class Person { private RecIpDet _ipDet; public RecIpDet IpDet { get { if(_ipDet == null) _ipDet = new RecIpDet(); return _ipDet;

从访问器返回新实例是否存在问题?如果是,有没有更好的方法

public class Person
{
    private RecIpDet _ipDet;
    public RecIpDet IpDet
    {
        get 
        {                 
            if(_ipDet == null)
                _ipDet = new RecIpDet();
            return _ipDet; 
        }
    } 
}

存在一些问题,因为您从未设置字段,所以每次调用属性时都会返回一个新对象

如果
\u ipDet
为空,则应设置它,然后返回它。这就是所谓的

请记住,这不是线程安全的,所以如果这是一个因素,您将需要一个更健壮的机制。对于单线程应用程序,这种延迟实例化方法很好

如果您使用的是.NET 4.0或更高版本,则可以使用我认为是线程安全的类:

public class Person
{
    private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>(() => new RecIpDet());

    public RecIpDet IpDet
    {
        get 
        {                 
            return _ipDet.Value; 
        }
    } 
}
公共类人物
{
private Lazy _ipDet=new Lazy(()=>new RecIpDet());
公共互惠
{
得到
{                 
返回_ipDet.Value;
}
} 
}

根据您的评论,您似乎确实想设置实例,因此这是一个典型的延迟实例化示例,虽然不是线程安全的,但是很好。如果您不需要担心线程安全,那么无论如何,这将起作用:

get
{
    if (_ipDet == null)
        _ipDet = new RecIpDet();

    return _ipDet
}
但是如果您使用的是.NET 4.0,我建议您使用
Lazy
,而不是构建自己的Lazy结构:

public class Person
{
    private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>();

    public RecIpDet IpDet
    {
        get { return _ipDet.Value; }
    } 
}
公共类人物
{
private Lazy _ipDet=new Lazy();
公共互惠
{
获取{return}ipDet.Value;}
} 
}

Lazy的值在第一次调用时调用类型的构造函数,并且是线程安全的(您可以选择不同的)线程安全级别。

现在,您将始终返回一个新对象。除非以某种方式将ipDet设置为一个值。这使得代码的行为非常不可预测。
实现singleton模式并替换return new RecIpDet();带_ipDet=新的RecIpDet();或者让它总是返回一个新对象,这很好。

对于我们来说,通常使用:

get
{
    return _ipDet ?? (_ipDet = new RecIpDet());
}

使用惰性实例化是很不寻常的,大多数情况下它是针对单例模式的,在这里您可以找到更多关于这方面的信息:

在本页中,您甚至可以找到一种使其线程安全的方法


它对于可以从应用程序中的任何位置访问的全局对象都非常有用。

奇怪的是,为什么不将_ipDet设置为新实例?这是我的错。那么问题是什么?现在,get访问器不会返回新实例。这个问题与题目不符。
get
{
    return _ipDet ?? (_ipDet = new RecIpDet());
}