5

我有一个属性定义为...

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; }
} 

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

有没有办法在不创建私有支持字段的情况下做到这一点?

4

6 回答 6

12

必须创建一个私有字段:

    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();
    }
于 2013-06-02T18:24:59.670 回答
3

不,没有支持字段就没有办法做到这一点。与问题无关,但与情况有关。通常,您不应该为集合公开一个 setter,而应该只公开一个 getter。如果你有一个设置器,你经常会暴露对象的内部状态,应该保持隐藏状态。

于 2013-06-02T18:24:27.803 回答
1

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; }
} 
于 2013-06-02T18:27:06.460 回答
0

No, not really.

In your code, when you check for if (Objs == null) - you are effectively using the get method in which you are currently in. So Objs { get; } calls itself, and that's why it's always recursive.

Remember that auto properties (get; set;) is really just a shorthand for having a backing field and separate get and set methods. Without that magic, your code would look like this:

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

What you are really implementing in your post is this - notice how GetObjs() is calling itself multiple times. So for every time it calls itself, it will eventually lead to it calling itself again. And again, and again.:

public List<Obj> GetObjs() {
    if (GetObjs() == null)
    {
        SetObjs(new List<Obj>());
    }
    if (GetObjs().Count < 1)
    {
        GetObjs().Add(new Obj());
    }
    return GetObjs();
}
于 2013-06-02T19:05:12.523 回答
0
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; 
   } 
}

公开集的目的是什么?

于 2013-06-02T20:48:54.860 回答
0

您应该使用私有字段来存储 Objs 列表。您无法从 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; }
}
于 2013-06-02T18:26:52.557 回答