Setting value in-line

Viewed 126

With all the awesome stuff we can do in C#, I was wondering if we could do something like the below:

  string totalWording =
  {
    if (isA)
      return "Value A";

    if (isB)
      return "Value B";

    if (isC)
      return "Value C";

    return "Default";
  };

So this would be very similar to the ?: except you can have more than 2 possible outcomes

string totalWording = isA ? "Value A" : "Default";

I could happily create a method that returns the value, but I'm a big fan of being able to see the simple stuff straight away

private string GetTotalWording()
{
  if (isA)
    return "Value A";

  if (isB)
    return "Value B";

  if (isC)
    return "Value C";

  return "Default";
}

I'd like to hear if anybody has something nice I can use, or if I'm just living on a prayer.

Edit:

There is the func option too, which is what I suppose got me onto the topic, as it looks you should be able to straight-up use a function when declaring a value.. but that might just be me

    Func<string> getTotalWording = () =>
    {
      if (isA)
        return "Value A";

      if (isB)
        return "Value B";

      if (isC)
        return "Value C";

      return "Default";
    };
2 Answers

Use repetitions of ternary operator.

string totalWording = isA ? "Value A" : (isB ? "Value B" : (isC ? "Value C" :  "Default"))

There is another way, if you only have manage-able number of if's and they remain same always. Create an enum with string values.

Below answer is based on another on Stack Overflow

You can create an enum for these statements with description.

public enum Values
    {
        [Description("Value A")] A,
        [Description("Value B")] B,
        [Description("Value C")] C,
        [Description("Value D")] D
    }

Then, you can create a function to get enum description

private static string GetEnumDescription(string text)
{
    var valueAttribs = typeof(Values).GetMember(text)[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
    return ((DescriptionAttribute)valueAttribs[0]).Description;
}

and you can then use these as

var variable = "A";

    string description = 
      (Enum.IsDefined(typeof(Values), variable)) ? 
          GetEnumDescription(variable) : "Default";

    Console.WriteLine(description);
    Console.ReadLine();

You could nest the method and lay it out more succinctly, so it looks more like this:

void someMethod(bool isA, bool isB, bool isC)
{
    string totalWording() {
        if (isA) return "Value A";
        if (isB) return "Value B";
        if (isC) return "Value C";
        /*Else*/ return "Default"; }

    // Other code...

    string s = totalWording();

    // Etc
}

I personally find that more readable.

If you can't use C# 7 you can do a similar thing with a Lambda in earlier versions, as you've already noted in your question. I'll put a copy here for completeness:

void someMethod(bool isA, bool isB, bool isC)
{
    Func<string> totalWording = () => {
        if (isA) return "Value A";
        if (isB) return "Value B";
        if (isC) return "Value C";
        /*Else*/ return "Default"; };

    // Other code...

    string s = totalWording();

    // Etc
}

The reason I strongly prefer this to the version using the ternary operator is that when reading the ternary version I have to mentally translate it into the above code when trying to understand it.

If I have to do that, then I'd rather it was written down for me so I didn't need to expend the effort. Perhaps that's just me, and I'm lazy. ;)

Related