带有硬编码getter和setter的C#属性

本文关键字:setter 属性 getter 编码 | 更新日期: 2023-09-27 18:16:24

我有一个定义为…的属性

public List<Obj> Objs { get; set; }

我想做的是在get方法中加入一些逻辑,所以它看起来像。。。

public List<Obj> Objs
{
    get
    {
        if (Objs == null)
        {
            Objs = new List<Obj>();
        }
        if (Objs.Count < 1)
        {
            Objs.Add(new Obj());
        }
        return Objs;
    }
    set { Objs = value; }
} 

现在,当我这样做的时候,我得到一个错误,告诉我函数在所有路径上都是递归的。

有没有一种方法可以做到这一点,而不创建一个私人支持领域?

带有硬编码getter和setter的C#属性

必须创建一个私有字段:

    private List<Obj> _objs;
    public List<Obj> Objs
    {
        get
        {
            if (_objs== null)
            {
                _objs= new List<Obj>();
            }
            if (_objs.Count < 1)
            {
                _objs.Add(new Obj());
            }
            return _objs;
        }
        set { _objs= value; }
    } 

为什么这是不可能的?让我们在Java中做同样的事情:

    private List<Obj> objs;
    public List<Obj> getListObjs()
    {
        ...
        // Recursion
        return getListObjs();
    }

不,没有后备字段是不可能做到这一点的。与问题无关,但与情况有关。通常,您不应该为集合公开setter,而应该只公开getter。若您有一个setter,那个么您经常暴露对象的内部状态,那个应该保持隐藏。

您的属性在属性的get部分的定义中引用自己。这是非法的,因为它会导致getter以无休止的循环结束。您有一个自动实现的属性(第一个示例(,或者有一个带有支持字段的属性(由编译器为自动实现的特性自动生成(。你需要添加一个(最好是私有的(字段作为你的财产的后备存储:

private List<Obj> objs;
public List<Obj> Objs
{
    get
    {
        if (objs == null)
        {
            objs = new List<Obj>();
        }
        if (objs.Count < 1)
        {
            objs.Add(new Obj());
        }
        return objs;
    }
    set { objs = value; }
} 

您应该使用私有字段来存储对象列表。无法从get方法的get方法获取数据…:(是递归。

private List<Obj> _objs;
public List<Obj> Objs
{
    get { 
    if (_objs== null)
    {
        _objs = new List<Obj>();
    }
    if (_objs.Count < 1)
    {
        _objs.Add(new Obj());
    }
    return _objs;
 }
    set { _objs= value; }
}

不,不是真的。

在你的代码中,当你检查if (Objs == null)时,你实际上是在使用你当前所在的get方法。所以Objs { get; }调用自己,这就是为什么它总是递归的。

请记住,auto-properties(get; set;(实际上只是具有一个后备字段和单独的get和set方法的简写。如果没有这种魔力,你的代码会是这样的:

private List<Obj> _objs;
public List<Obj> GetObjs() { return _objs; }
public void SetObjs(List<Objs> objs) { _objs = objs; }

你在文章中真正实现的是——注意GetObjs((是如何多次调用自己的。因此,每当它呼唤自己时,最终都会导致它再次呼唤自己。一次又一次

public List<Obj> GetObjs() {
    if (GetObjs() == null)
    {
        SetObjs(new List<Obj>());
    }
    if (GetObjs().Count < 1)
    {
        GetObjs().Add(new Obj());
    }
    return GetObjs();
}
private List<Obj> objs = new List<Obj>() { new Obj() };
public  List<Obj> Objs { get { return objs; } }

或者如果你想防止有人删除最后一个Obj

private List<Obj> objs = new List<Obj>();
public List<Obj> Objs 
{ 
   get 
   { 
       if (objs.Count == 0) objs.Add(new Obj());
       return objs; 
   } 
}

公共布景的目的是什么?