I am a Java dev for almost all of my programming (at least in the workplace) but I do some Unity for fun on the side. I have used C# properties many times and they are convenient to still provide encapsulation without having to write out getter and setter methods.

With that said, is there any disadvantage to writing actual getter and setter methods for fields instead (other than my time)? Assume this is within my personal Unity code for fun and not in any sort of work or shared dev environment.

  • 6
    This is basically "I know programming language X has for, while, and switch blocks, but is there any disadvantage to just using goto instead" – whatsisname Nov 22 '19 at 6:37
  • Unity's tooling will treat a property differently to a pair of methods – Caleth Nov 22 '19 at 15:14
  • in c#, properties are the idiomatic way to provide getters and setters. There is a get() function and set() function behind every property already. You can take advantage of those if you want. No need to go out of your way to create another. – Eric King Nov 22 '19 at 15:35

C# properties are made of methods. Thus, by using methods instead of properties, you do not get any runtime advantages.

Instead it will be all about developer productivity and readability of your code.

Readability is for yourself too. In a few months when you forgot the details of your code and you need to modify it to fix a bug or add a new feature. Even if you do not care about that, you probably care about doing more with the same amount of code.

On the productivity side, we have that properties have the advantage of requiring to write less code. Much more if we are talking about auto-properties. About readability, they result in less verbose code (less Get, less Set and less ()).

Properties may also affect discoverability. As having getter and setters will result in the methods associated with the same field being separated in intellisense.

However, there are some arguments for methods. For instance, if setting a value can fail, you might want to use a method and return bool so you can communicate to the caller if the set failed. You could, in theory, get away with using a property... after all, the caller can read the property after setting it to check if the value was set. However, returning bool is a thread-safe ready API.

Another case is when the property has to do a long computation to return a value. Using a method conveys that it is doing something behind the scenes. Similarly, using a method instead of a property can convey that reading the value could have side effects (it is not pure). Addendum: This is not a hard rule. Yet, in general a method does something, it is an action. On the other hand, we expect to be able to read properties at any time without major consequences.

Finally, if you have a property that returns an array, it could be missed for an indexer. It is preferred to provide an actual indexer or use a method to avoid confusion.

By the way, Alan Kay, who coined the term object-oriented, does not like setters. Instead, state should be encapsulated. He said:

Lots of so called object oriented languages have setters and when you have a setter on an object you turned it back into a data structure.

For Alan Kay, letting third parties change the state of the object unexpectedly is a bad idea.

With that in mind, let met tell you about a couple cases where properties are a bad design:

  1. Avoid providing properties as a mean to decide what to do. The caller code should not have to read properties of your object to decide what method to call. Instead encapsulate that logic in the methods of your class. That is, with object-oriented design, prefer Tell, Don't Ask.

  2. Avoid properties that change the behavior of methods. If you have them, you will end up with code that backups the value of a property, change the value, calls the method, then restores the value. Instead add that value as a parameter to the method (even if you need to add it to virtually every method in the class). That makes for a much easier to use API, follows the principle of least astonishment, and it is better for thread-safe code.

Properties, in particular readonly properties, remain very useful for logging and debugging. Also there are things that depend on properties to work, such as some forms of serialization and data binding.

  • 3
    Everything mentioned in this answer seems right. I would add that many frameworks and IDEs rely on properties, not methods, to work on. For example, on Visual Studio, when designing a UI using web or desktop components. So, properties should express "attributes of something" (like height, birthDate, color), while methods should express more "actions" (like expensive calculations that should be cached by caller, or things that mutate the state or affect multiple properties). – DanielCuadra Nov 22 '19 at 6:14
  • 1
    "Another case is when the property has to do a long computation to return a value" Just to slightly extend: I would suggest the same applies in cases where setting a value leads to multiple values changing, even if not a long computation. The method suggests that logic is being executed (more so than just a single value being set). – Flater Nov 26 '19 at 11:12

Keep in mind that properties are "actual getter and setter methods." A property is nothing more or less than one or two methods, along with a piece of metadata saying "this is a property." The syntax for calling a property method is different from the syntax for calling an ordinary method, but aside from that, a property method works exactly the same way as any other method.

That said...

With that said, is there any disadvantage to writing actual getter and setter methods for fields instead (other than my time)? Assume this is within my personal Unity code for fun and not in any sort of work or shared dev environment.

In your own personal code? No, not really.

The main disadvantage is that when other people read your code, they're likely to get the wrong idea about what's happening. If you write deflection = surface.Deflection, I'm going to guess that finding the deflection value is fast and easy. If you write deflection = surface.GetDeflection(), I'm going to guess that finding the deflection value involves something slow or difficult, like reading a file, or communicating with a sensor which will determine the deflection.

In other words, the usual way to write getters and setters is to write them as C# properties, so if you don't write them as C# properties, people are going to assume that you had some particular reason for not doing that.

And, of course, if you ever write C# as part of a team later on in your life, the team is probably going to want you to write getters and setters the "normal" way, so you may want to get in the habit now.

But if you'd rather read and write controller.SetProcVar(aircraft.GetAttitude().GetBankAngle()) than controller.ProcVar = aircraft.Attitude.BankAngle, then that's not going to cause you any unexpected problems.

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