6

I have this example class:

public class Carrots
{
    private string name;

    public void SetName(string pName)
    {
        name = pName;
    }

    public string GetName()
    {
        return name;
    }
}

I have the member of the class set as private and to set and get this member, I have made get and set methods. Is there a way I can make this code shorter and easier to read at a glance?

8

Using properties

A proper getter and setter would look like this:

public class Carrots
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

(Click here if you don't understand the role of the keyword value in this example).

Using auto-properties

In c# 3.0 and later, you can also use auto-properties, making it even easier.

public class Carrots
{
    public string Name { get; set; }
}

If you want the public property to be read-only (but still want a private setter) you can use:

public class Carrots
{
    public string Name { get; private set; }
}

How to call it

In both cases, you would call it like this:

var c = new Carrots();
c.Name = "This is a test!";
Console.WriteLine(c.Name); //outputs "This is a test!"
  • Regarding auto-properties, how would you do this with the string set to private as in your example it is public? – Gigabit Mar 25 '17 at 2:10
  • In my example, there is still a private string that can only be accessed via the auto-properties. The public keyword next to Name indicates that the properties, not the variable, is public. The private string is created implicitly and has a funny name-- if you are curious about it, see this post. – John Wu Mar 25 '17 at 2:12
  • 1
    Sorry, I misread what you wrote and now I have re-read it, it makes perfect sense. Thank you hugely for your help. – Gigabit Mar 25 '17 at 2:16
  • I have implemented your method but Visual Studio is telling me "The field 'Carrots.name' is never used'? – Gigabit Mar 25 '17 at 3:08
  • Which approach did you use and what does the code look like? Maybe you should ask a separate question on this forum. – John Wu Mar 25 '17 at 3:09
0

Shorter and easier to read would be something similar to:

public class Carrots
{
    public string Name { get; set; }
}

This uses an internal private variable that is used when the property is accessed. Equivalent to:

public class Carrots
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

(As @John Wu demonstrated.)

However, it will depend on what you are wanting external code to be able to access.

If you just want a 'Name' to be instantly changeable and it has no bearing on the application when it is, the above public string Name { get; set; } is all you will need.

But if you are tracking/using/controlling the value of a property within your class and you don't want external code changing it, then the second example is the one to go with.

For instance:

You have a class that is created with a known value. You want that value to be changed - but under your control.

A bank balance perhaps? Or the speed of a car?

Lets go with speed of a car:

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
    // Notice no setter in this case.
    }

    public void IncreaseSpeed()
    {
        if(_speed + 1 <= 100)
        {
            _speed++;
        }
    }

    public void Brake()
    {
        if(_speed-- >= 0)
        {
            _speed--;
        }
    }
}

This lets the calling code call to increase speed, or slow down holding the brake, as many times as they want. But you can now put a realistic limit on that speed - the user cannot break the rules you have in you application's 'world'.

Here is another example but the external code can set the value immediately:

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
        set {
                if (value >= 0 && value <= 100)
                {
                    _speed = value;
                }
            }
    }
}

This now lets the calling code handle acceleration and braking, updating the Car object when it wants to. But you still have the overall control of what that value can be, rather than controlling how it is changed.

Using:

public class Carrots
{
    public string name;
}

as @Charles Merriam demonstrated is all well and good if you don't care when, and to what value, external code will set this property. It is always public, and never checked when altered.

It should never be accessed by your class's internal methods if it requires boundaries as to what state it should be in or requires a particular range. You would need to use the boundary checking logic everywhere that accesses it (then handle any errors if the checks fail), rather than preventing invalid data input altogether.

-2

Just a quick few things:

  • You are using getters and setters in the construct because of limitations in your language and its inability to inhibit the 'address of' operator on members.
  • You are using getters and setters because there might, possibly, be a future in which you replace the data items with complex functions, and the language does not support overriding the '.' operator correctly.
  • You are using getters and setters because everyone else does it, it becomes part of the lore, and part of the development schedule and executable speed bloat.

If working in a team, an alternate approach is to dump the getters and setters, use direct access to the fields, and have a chat with developer doing something stupid to the field.

So you write:

public class Carrots
{
    public string name;
}

and access as myCarrot.name

  • 1
    This is bad design though; it allows consumers of the class to break encapsulation, and the class can't prevent invalid data from being set. Some other things won't work properly either, notably the built-in serialization classes, which only serialize properties, not fields. – Andy Mar 27 '17 at 0:52
  • Ah, the mitigation of the flaw is a matter of opinion. The design flaw is down in the language, because you can cant prevent someone from passing &(foo.buf) to some async routine, so you get stuck with too much cruft. You can mitigate by burning programmer time, using tons of boilerplate code, rules of three, etc. You can mitigate with process and tools, preventing this with peopleware. – Charles Merriam Mar 28 '17 at 5:55
  • 2
    You're not even making sense anymore... – Andy Mar 29 '17 at 0:55
  • I think you are exclusive to C++ derivatives. Talk to Bjarne about his views on the rise of setters. Many other languages use declarations that a field is meant to be a property, and many simply disallow memory access into classes. There is no encapsulation difference in dereferencing a field, except in C++, C#, and the like. Consider it a flaw of time, like emacs not having an event system, and code around it. – Charles Merriam Mar 29 '17 at 3:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.