Use null-conditional operator to set value to 0 if null

user2328273 picture user2328273 · Jan 30, 2018 · Viewed 7.6k times · Source

I'm new to C# but not to programming in general. I am trying to set add some error checking to my program. There are 3 textboxes and I am trying to make it so that if the text box is left blank, it assumes a value of 0. Here is my code so far:

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        if (String.IsNullOrEmpty(txtNumberOfClassATix.Text))    // Assumes 0 if no number entered for txtNumberOfClassATix.Text.
        {
            txtNumberOfClassATix.Text = "0";
        }
        if (String.IsNullOrEmpty(txtNumberOfClassBTix.Text))    // Assumes 0 if no number entered for txtNumberOfClassBTix.Text.
        {
            txtNumberOfClassBTix.Text = "0";
        }
        if (String.IsNullOrEmpty(txtNumberOfClassCTix.Text))    // Assumes 0 if no number entered for txtNumberOfClassCTix.Text.
        {
            txtNumberOfClassCTix.Text = "0";
        }
        int classANum = int.Parse(txtNumberOfClassATix.Text);
        int classBNum = int.Parse(txtNumberOfClassBTix.Text);
        int classCNum = int.Parse(txtNumberOfClassCTix.Text);
        double classATotal = classANum * classAPrice;
        double classBTotal = classBNum * classBPrice;
        double classCTotal = classCNum * classCPrice;
        lblCalculatedClassARevenue.Text = $"{classATotal:c}";
        lblCalculatedClassBRevenue.Text = $"{classBTotal:c}";
        lblCalculatedClassCRevenue.Text = $"{classCTotal:c}";
        lblCalculatedTotalRevenue.Text = $"{(classATotal + classBTotal) + classCTotal:c}";
    }

This code works but I'm sure I could replace those if statements with something simpler. I've seen how to set a variable to null if another is null using the null-conditional operator but I don't really grasp it enough to adapt it to my scenario.

Answer

Eric Lippert picture Eric Lippert · Jan 30, 2018

So far maccettura's answer is the best, but can we do better? Sure we can. Let's make a general-purpose extension method:

internal static class Extensions 
{
  public static int? AsInt(this string s)
  {
    int result;
    if (s == null)
      return null;
    else if (int.TryParse(s, out result))
      return result;
    else
      return null;
  }
}

And now:

    int classANum = txtNumberOfClassATix.Text.AsInt() ?? 0;

If it's an int, you get the int. If it's not, you get zero. Easy peasy.

Or, you might want this extension method:

internal static class Extensions 
{
  public static int AsInt(this string s, int default = 0)
  {
    int result;
    if (s == null)
      return default;
    else if (int.TryParse(s, out result))
      return result;
    else
      return default;
  }
}

And now you can say what you want the default to be without using ??.

This style of programming is called "fluent programming"; it can make code that is very easy to read and understand.

Notice that this solution does not update the UI with zeros; if you wanted to do that then I would recommend splitting that into two steps: one which causes the mutation, and then a separate step which computes the value. Operations which are useful for both their effects and their values can be confusing.