0

I have a property in my class:

public int Points { get; set; }

At some point it's being set to less than 0 but I am not sure where. I suspect it is in this code:

phrase.Points += -(int)Settings.ABtn;

How could I change this so that Points could never be set to less than zero?

Alan2
  • 23,493
  • 79
  • 256
  • 450
  • 1
    The question I have is, do you actually want the value to never go negative or do you want to fix a potential bug somewhere else where something is trying to add a negative value? Fixing at the setter level is going to answer your question, it would also tell you what is setting your value to less than zero if you throw an exception in your code when you receive a negative amount (you can then debug the caller and see what it was doing). Fixing what you "think" the bug might be isn't going to guarantee anything – Charleh Feb 07 '20 at 16:01
  • Yes, there seems to be a lot of over thinking going on here, rather than answering the question as asked... Please confirm what you want. – rfmodulator Feb 07 '20 at 16:02

5 Answers5

3

You can check the value in the property's setter:

private int _points;
public int Points 
{ 
    get => _points; 
    set
    {
        _points = (value > 0) ? value : 0; 
    }
} 
Marco Salerno
  • 5,131
  • 2
  • 12
  • 32
Miamy
  • 2,162
  • 3
  • 15
  • 32
2

Make the property have a backing field and change the implementation:

private int _points;
public int Points 
{ 
  get 
  {
    return _points;
  }
  set
  {
    _points = value;
    if (_points < 0) 
      _points = 0;
  } 
}

One of the main points of properties vs fields is that you can change the implementation of a property without changing to the public interface.

To your caller it still looks like they are setting a value - you could also throw an exception if the value drops below zero if that's what you need.

Charleh
  • 13,749
  • 3
  • 37
  • 57
0

You have 2 main ways to approach this, as far as I can see it:

1) Make the variable type uint instead of int. uint is an unsigned integer number, ranging from 0 to 18446744073709551615 (You can read more about variable types in Wikipedia. I do recommend you to, since it is an important topic). Moreover, you will get an exception when trying to make a uint less than 0, so you will be able to know where exactly something went wrong.

2) You can simply use the Math.Abs() method, which returns the absolute value of a number (e.g entering -9 will give back 9, and so would entering 9).

Just as a side note, you can make that line a bit simpler by changing it to:

phrase.Points -= (int)Settings.ABtn;
E. Epstein
  • 739
  • 2
  • 11
  • 26
0
phrase.Points = Math.Max(phrase.Points += -(int)Settings.ABtn, 0);
rfmodulator
  • 3,638
  • 3
  • 18
  • 22
  • 1
    Thanks, I think this would work. Let's see if anyone else can find any issues with your suggestion. – Alan2 Feb 07 '20 at 15:50
  • 1
    This isn't going to prevent the property from dropping below zero, it just prevents the caller from sending a negative value. If the question calls for the value to never drop below zero then the correct approach is to prevent this at the setter level, not fix all the callers. If you don't know where in the code the negative value is coming from but you want to ensure that the value never drops below zero, this code is only going to ensure that this particular line always results in a non-negative value. – Charleh Feb 07 '20 at 15:58
0

You can make the Points property an uint like this :

public uint Points { get; set; }

uint means it's unsigned so it'll never go below 0, if you want to know more about the differences between int and uint see this question

nalka
  • 1,894
  • 11
  • 26