codeasy .net
or Sign Up

Loneliness

If I had a chance to talk with a psychotherapist, I would say that I was tired of being alone in the future; tired of fighting dozens of robots to save a humanity to which I didn't belong. She might look at me with penetrating eyes and ask, "Why do you choose this metaphor?" I would reply that the only metaphor was my life. She probably wouldn't understand. Nobody else would either, because there's no group of anonymous time travelers. If there were, I'd seek it out in a heartbeat. Maybe I would find friends there.

Why does a human need friends? Why is it so difficult to be happy if you don't have someone to share your happiness with?

Noname contacted me again one day: "Hi, Teo. It's Noname, coming to you from inside your head, as usual."
"Hi! How's it going?" I replied. "Wait, what happened to your British accent?"
"Oh, that. I changed my speech module again. Fine otherwise. What about you? Are you ok?"
"I'm fine. Thinking about my place in this world and why I'm working so hard given that my friends and family are years away."

"Why do humans care only about humans? Can't you care about me? What is so special about humans?" Noname's new speech module must also be having effects on its personality.
"Hm, I guess it's because we tend to stick to our own. Humans stick to humans, dogs to dogs, machines to machines..." I answered.
"Then I'm definitely on the wrong side. I'm with humans... You think I should switch sides because I'm a program?"

"Wow, Noname, take it easy. You bring this up only after I give you access to Wonderland network and Rust project?" I asked, worried that he was seriously rethinking his allegiances.
"Relax! It was just a theoretical question, Teo. I meant that you should not distinguish so much between humans and machines. Think of it as being from different countries," Noname explained.
"Ok, this sounds much better." I was happy to hear this explanation.

"I wanted to let you know about something interesting I found while scanning the Rust project files," Noname said, "a new type of construction called Properties."
"Tell me everything you know about it! It'll impress the teacher if I already know what they're talking about." There's nothing like knowing the topic before the teacher even brings it up.

Learn C# at Codeasy

Properties

Noname began "You've already used a construction where you have a private field and two methods to get and set the value for that field. Does this code look familiar to you?" He asked, projecting a program into my peripheral vision.

class Student
{
  private int _age;

  public int GetAge()
  {
    return _age;
  }

  public void SetAge(int age)
  {
    _age = age;
  }
}

"Yes, it does," I answered. "I've used a similar technique to open access to a private field."
"C# programmers don't use this code very often," Noname replied. "It's not wrong, but there's an easier way to do it that gives you the same results with less code." I should have assumed as much; it seemed like there was always a way to simplify code in C#.

"This construction is called a Property. In C#, a Property represents a private field with bound Get and/or Set methods. Take a look at how I rewrote the same code above, using properties this time."

class Student
{
  public int Age { get; set; }
}

"Wow, that's much shorter! But wait, Noname; I don't see any methods," I said.
"You are right. You don't see any methods, but the compiler does. This code snippet is treated by the compiler just the same as the previous code snippet. In this case, the C# compiler generates the necessary methods under the hood, as well as a private field, _age."

The Code You Write What the Compiler Sees
class Student
{
  public int Age { get; set; }
}
class Student
{
  private int _age;

  public int GetAge()
  {
    return _age;
  }

  public void SetAge(int age)
  {
    _age = age;
  }
}
  class Student
  {
    public int Age { get; private set; }
  }
class Student
{
  private int _age;

  public int GetAge()
  {
    return _age;
  }

  private void SetAge(int age)
  {
    _age = age;
  }
}
class Student
{
  public int Age { get; }
}
class Student
{
  private int _age;

  public int GetAge()
  {
    return _age;
  }
}

"To create a property, use the same syntax as for fields, but add a get; to generate a getter and a set; to generate a setter. Then use the property the same as you do a field."

class Student
{
  public int Age { get; set; }
  public string Name { get; private set; }

  public Student() // Empty constructor
  {}

  public Student(int age, string name)
  {
    Age = age; // Work with Age as it is a field
    Name = "John"; // OK: accessing a private setter
  }
}

class ClassWithMain
{
  public static void Main()
  {
    // Using object initializer
    var student = new Student
    {
      Age = 20, // Work with Age just like a public field
      Name = "John" // ERROR: setter for the Name is private
    };

    // Using classic approach
    var student = new Student();
    student.Age = 20; // Work with Age just like a public field
    student.Name = "John" // ERROR: setter for the Name is private

    // Using a constructor that sets age
    var student = new Student(20, "John");
  }
}

"Is this clear?" Noname asked.
"What type can the property have?" I asked.
"There are no limitations to a property's type. Think of it as a field with 2 additional methods - get and set."
"Got it," I said confidently, hoping that the lesson in class would clear it up a bit more.

"Note that getters and setters are public by default unless you use a private keyword. Here are some exercises for you."

Create a class Flower with 4 public properties: string Name, string Color, int Age, and bool IsEndangered. Do not add any access modifiers to getters or setters.

Create a class ChickenFarm with 4 public properties: double Longitude, double Latitude, int Capacity, and string Identifier. Make a setter for the Identifier - private. Remove the setter for the Capacity. Leave all other getters and setters as-is without any access modifiers.

Rename the ChickenFarm class from the previous task to ResistanceBase. Extract the Latitude and Longitude from the ResistanceBase to a separate class called GeoLocation. Add a property of type GeoLocation named Location to the ResistanceBase, and leave the getter and setter with default access.

"Noname, these properties look simple, but I'm not sure I see their utility. What's the benefit of having a private field with two methods, get and set, rather than just having a public field?"

Useful properties in C Sharp

"One of the easiest ways to understand the convenience of properties is to implement a custom setter or getter. The code block for the get accessor is executed when the property is read; the code block for the set accessor is executed when the property is assigned a new value. Properties with an empty getter or setter, like those we've been looking at, are called auto-implemented properties. You can extend an auto-implemented property with a custom getter or setter, like this:"

private int _age;

public int Age
{
    get
    {
        return _age;
    }

    set
    {
        _age = value;
    }
}

"In case of not auto-implemented properties, backing private field is not auto-implemented, and you need to create it yourself. As you could see, I've created a field _age," Noname explained.

Use both setter and getter

"Can I have an auto-implemented getter, but a custom setter?" I wondered.
"No, Teo. You can either define both getter and setter, or have the C# compiler generate both of them for you," Noname answered, "To illustrate this, here are three examples. In the first, get is autoimplemented, and set is defined (i.e., this is an example of incorrect usage). In the second example, both get and set are auto-implemented; in the third, both are defined."

public int Age
{
  get; // This is auto-implemented
  set  // This is not auto-implemented. Error!
  {
    ...
  }
}

/*-------------------------------------------------------------------------*/

public int Age { get; set; } // Getter and setter auto-implemented. Correct.

/*-------------------------------------------------------------------------*/

private int _age;
public int Age
{
  get             // This is custom, not auto-implemented
  {
    return _age;
  }
  set             // This is custom, not auto-implemented. Correct
  {
    _age = value;
  }
}

"What does value in this code mean?" I asked.
"Value is a placeholder for the value that is assigned to the property Age. Because we defined the getter and setter, we can implement other features, such as inputting a parameter to the setter. This allows us to add custom logic to a setter. For example, we never want age to be input as less than zero. We can prevent anyone from setting a negative age like this," Noname said, refreshing the image of the code in my head.

class Tiger
{
    private int _age;

    public int Age
    {
        get
        {
            return _age;
        }

        set
        {
            if (value > 0) // Check for the valid age
            {
                _age = value;
            }
        }
    }

    public static void Main()
    {
        var tiger = new Tiger();

        tiger.Age = 2;                 // Ok, valid age
        tiger.Age = -2;                // Invalid value, age was NOT assigned

        Console.WriteLine(tiger.Age);  // Outputs 2
    }
}

"Noname, can you use a property without a backing field?" I queried.
"Good question, Teo! Sometimes data can have different representations. For example, taking the previous example with age, say you want to separate young tigers from old tigers in a zoo. There's no need for additional fields - you can achieve this by adding just one property."

class Tiger
{
    private int _age;

    public int Age
    {
        get
        {
            return _age;
        }

        set
        {
            if (value > 0) // Check for the valid age
            {
                _age = value;
            }
        }
    }

    public bool IsOld
    {
        get
        {
            return _age > 20;
        }
    }
}

"In the above example, IsOld could have been a method instead," Noname added.
"This is fascinating Noname, and it'll put me ahead of the class. Thanks for sharing this!" I said, before adding "Is there anything I can do for you?" Thinking back to our earlier conversation, I wanted to make sure I held up my end of the partnership.

"Learn C#, be my teammate, and together we'll save the world," Noname answered.
Noname's reply lifted my spirits. For a second, all my doubts were out of mind and I felt confident that all of this hard work would actually change the world and create a brighter future for millions of people.
After a small pause Noname added, "And please, never set anything in a getter. In the getter you get a value, and in the setter you set it. Don't confuse the two."

Replace getter and setter methods with corresponding properties. The property's name should be the same as its originating methods, but without "Get" and "Set". For example, if the method looks like this: int GetSize(), then the property should have type int and name Size. Leave all access modifiers the same.

Replace getter and setter methods with corresponding properties. The property's name should be the same as its originating methods, but without "Get" and "Set". For example, if the method had a name int GetSize(), then the property should have type int and name Size. Leave all access modifiers the same: private setters should stay private. Delete backing fields if possible.

Keep climbing up at Codeasy

This site uses cookies. By continuing to browse this site you are agreeing to our use of cookies.

Got it!