Darkbound
Darkbound

Reputation: 3434

Is a Property necessary if the field is used only for internal logic?

I know how properties are used to expose fields, what are the benefits and so on. What I am trying to understand (and I've searched quite a bit) is:

Does every single field need to always have a wrapping property, even if it does NOT need to be exposed and is used only in internal logic?

I would assume that the answer is yes, because even if its modified in some internal logic, the new value would still need to be validated.

If the answer is yes, is this why its so common for a property to have public get and private set?

Edit: Thank you for all the answers that you gave me, but most of them have nothing to do with my question, most of you are talking about big and complex classes, my simple question is, should I have a wrapping property for a field thats used only inside its class and does not need to be exposed.

Edit 2: Some of the answers suggest something that can be accepted as a no answer, suggesting that a property should not be used if there is no need for logic

Edit 3: Thank you all, I reread most of the comments and it started making sense, just like always :)

Upvotes: 1

Views: 261

Answers (3)

This isn't one of those issues where you can do a whole lot of damage getting it wrong.

That said, no, don't make it a property unless you need to put some logic in the setter or getter, and you probably don't need to. Don't add code that doesn't serve some purpose.

"Fields are bad" isn't a purpose. And in fact, it's nonsense. Fields exist for a reason.

If the class is so huge that nobody can keep track of it all and you need to hide parts from each other, it's too big and it's doing too much. Refactor it into two or more classes that are manageable.

Very often, as a large class grows (most often something that doesn't naturally have a very tight focus, like a major viewmodel, or Window or a Form in the bad old days), we find ourselves writing little "subsystems" within the class that have a field or two with logic in the set and/or get blocks. That's a candidate for refactoring into a separate small class with a clean interface, an easily reusable ball of logic and state that doesn't have its internals mixed in with your big class's internals. Give the big class a private copy of the little helper class. Drag and drop code is an example that springs to mind.

It's a classic progression:

  1. I'll just add a flag
  2. That flag I added yesterday has to be an enum
  3. With a flag
  4. Wait, I just copy and pasted a block of code. Put that in a setter on the flag.
  5. And a hel... two helper methods.
  6. Let's put a #region around that mess so I don't have to look at it.
  7. We're going to have to copy and paste that whole mess into another class. Good thing it's all in one place!
  8. It wasn't all in one place.
  9. What's my manager doing with that jacket with the funny sleeves?

If you ever reach Stage 7, it's past time for an intervention.

Private properties are just the first tiny whiff of what may turn into a noxious code smell over time. They're not evil, but they may be a sign that your code is showing a tendency to grow on the wrong axis.

Update

On internal vs external validation

Very often, a class needs to be able to break its own rules, and do so cleanly and straightforwardly. For example, validation of one property/field often depends on values of others (date ranges, etc.). Your classe's internals should be able to set them all in arbitrary order without any funny business (sometimes you see "_disableValidation" flags to work around this issue -- a code smell). Inside the class, validation should be voluntary, and the class should be kept simple enough so that isn't a problem. A class needs to permit itself to put itself in an invalid state temporarily, while forbidding or controlling the ways in which any external code can put it in an invalid state. Maybe if external code puts it in an invalid state, that's permitted by code, but it drives UI that hassles the user. You don't want to have weird flags to allow your constructor to do its job without popping up a message box or something.

Sometimes a class needs to run around nekkid in the privacy of its own home. Validation should be on inputs from code external to the class.

Upvotes: 3

Fabio
Fabio

Reputation: 32455

YAGNI

if you don't use property - do not create it.
If you need change field some how or change logic how it created/updated you will be able to do it without property.

Because you do not expose it - you don't need to worry about breaking some other code.

if you have some "complex" logic which instantiate/update that field - create a private methods for it.

Putting some "extra" logic in the setter or even worth add some "side-effect" on the getter - can lead in some odd behavior or bugs, because when I initialize class

var order = new Order
{
    Id = 1001,
    Reference = "Reference one",
    CustomerId = 2001        
}

I do not expect that assigning CustomerId will cause in some database queries or execution of some complex logic. Instead

var order = new Order
{
    Id = 1001,
    Reference = "Reference one"      
};
order.SetCustomer(customerid);

Upvotes: -1

Measurity
Measurity

Reputation: 1346

There's no need to do it but by using a property instead of a field you're more flexible because you can preprocess getting and setting a variable. Changing a field to a property while it's already in use in other code can be a breaking change. So if you don't know what to choose, go with a property to be on the safe and most flexible side.

Upvotes: 1

Related Questions