DEV Community

loading...

Start using fields in C#. Using properties is not a good habit and won't do you any good...

lukaszreszke profile image Łukasz Reszke ・2 min read

A field is a variable of any time declared in the class. The fields are usually private, which means that they cannot be accessed from outside the class.

Field could be exposed by a public property - however, it's not recommended in every case.

Exposing a field by setter and getter might lead to an unwanted state of the system - that's because it's harder to keep control over what is assigned to a field.

Let's take the Address class as an example. If we expose just properties - we can write whatever we want into the zip code.

public class Address
{
    // Other properties
    public string ZipCode { get; set; }
}

static void Main(string args[])
{
    var address = new Address();

    address.ZipCode = "I can type whatever I want here!";
}
Enter fullscreen mode Exit fullscreen mode

Let's refactor it and see if we can do it better.

public class Address
{
    // Other parts of Address class

    private string _zipCode;

  public void SetZipCode(string zipCode)
  {
    if(!string.IsNullOrEmpty(zipCode) && zipCode.IsValidZipCodeFormat())
            _zipCode = zipCode;
        else throw new ArgumentException(nameof(zipCode));
  }
}

static void Main(string args[])
{
    var address = new Address();

    address.SetZipCode("81-840");

    address.SetZipCode("abcdefgh"); // throws Argument Exception

    // Not possible anymore
  // address.ZipCode = "I can type whatever I want here!";
}
Enter fullscreen mode Exit fullscreen mode

We encapsulated the knowledge of how to set the zip code and what rules have to be fulfilled within the SetZipCode method. Now, anyone calling this method will have to fulfill those rules.

Summary

Don't get me wrong, properties are awesome and they have their place. But I often see them misused and they're often a reason for lacking encapsulation. If possible - limit the possibility to modify your data with carefully crafted methods.

Join dotnetcoreschool.com and learn C#

Discussion (6)

pic
Editor guide
Collapse
hnicolas profile image
Nicolas Hervé

In your example you use default property setter and getter but you can define your own property accessors for this purpose which is much cleaner.

public class Address
{
    private string _zipCode;

    public string ZipCode
    {
        get => _zipCode;
        set
        {
            // validation
            if (string.IsNullOrEmpty(value))
            {
                throw new Exception("Invalid zip code");
            }
            _zipCode = value;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

docs.microsoft.com/en-us/dotnet/cs...

Collapse
lukaszreszke profile image
Łukasz Reszke Author

Hey Nicolas, you're totally right.
That's another way to do it :) Thanks for sharing!

Collapse
hnicolas profile image
Nicolas Hervé

It is the idiomatic way to do it.

Collapse
lifelongthinker profile image
Sebastian

Come on, Łukasz, your post doesn't need that click-bait title 😋

In case the ZIP Code is required in more than one place and circumstances allow it, I like to use a separate Struct instead of just a String. That way I can keep the entire ZIP logic and string formatting in one place and reuse it wherever I need it.

Collapse
lukaszreszke profile image
Łukasz Reszke Author

Yup, it's a little bit click-bait'ish... 😅

"In case the ZIP Code is required in more than one place and circumstances allow it, I like to use a separate Struct instead of just a String. That way I can keep the entire ZIP logic and string formatting in one place and reuse it wherever I need it." - Great example. I would use something similar to struct - Value Object. But that's for another topic :)

thanks for comment, Sebastian!

Collapse
lifelongthinker profile image
Sebastian

I came across this post again in my feed.

One question: Why don't you use separate visibilities for your accessors (as needed) and then combine them with custom validation logic as proposed by Nicolas? It's the official C# way of doing it and (as he rightly states) way more idiomatic.

Unlike Java, C# has had first-class properties from the start.