Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Property with hard coded getter and setter

Tags:

c#

.net

I have a property defined as...

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

What I would like to be able to do is to put some logic into the get method, so it would look something like...

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

Now when I do this I get an error telling me that the Function is recursive on all paths.

Is there a way to do this without creating a private backing field?

like image 570
jdavis Avatar asked Jun 02 '13 18:06

jdavis


3 Answers

You have to make a private field:

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

Why is it impossible? Lets make the same thing in Java:

    private List<Obj> objs;
    public List<Obj> getListObjs()
    {
        ...
        // Recursion
        return getListObjs();
    }
like image 124
Jean-Philippe Leclerc Avatar answered Nov 15 '22 02:11

Jean-Philippe Leclerc


No there's no way of doing it without a backing field. Unrelated to the question but related to the situation. You should in general not expose a setter for a collection but only a getter. If you have a setter you are very often exposing internal state of the object, that should be kept hidden.

like image 39
Rune FS Avatar answered Nov 15 '22 04:11

Rune FS


Your property refers to itself in the definition of the get part of the property. This is illegal as it would cause the getter to end up in an endless loop. You either have a auto-implemented property (your first example), or a property with a backing field (which is automatically generated by the compiler for auto-implemented properties). You need to add a (preferrably private) field as a backing store for your property:

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; }
} 
like image 45
Erik Schierboom Avatar answered Nov 15 '22 03:11

Erik Schierboom