I want something like a switch statement (but of course

Is there a C # construct, such as an operator switch, that lets you control the fall at the next level? I have something like this:

    public static IEnumerable<string> SeverityOrHigher(string severity)
    {
        var result = new List<string>();

        switch (severity.ToUpper())
        {
            case "ALL":
                result.Add("ALL");
            case "DEBUG":
                result.Add("DEBUG");
            case "INFO":
                result.Add("INFO");
            case "WARN":
                result.Add("WARN");
            case "ERROR":
                result.Add("ERROR");
            case "FATAL":
                result.Add("FATAL");
            case "OFF":
                result.Add("OFF");
            default:
                break;
        }

        return result;
    }

... which clearly does not work in C #, ( Control cannot fall through from one case label...), but it seems to me that it should. I know that he expects breaks there, but that will not give me the data stream that I am looking for. What can be done to make this happen as we would like?

+3
source share
7 answers

In your case, you can emulate a “falling case” using a little LINQ:

public static IEnumerable<string> SeverityOrHigher(string severity)
{
    var result = new List<string>() 
        { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
    return result.SkipWhile(l => l != severity.ToUpper()).ToArray();
}
+10
source

Along with gotos, etc. you can do an enumeration with that and a bit of linq:

    public static IEnumerable<Severity> SeverityOrHigher(Severity severity)
    {
        var value = (int) severity;

        return Enum.GetValues(typeof (Severity))
            .Cast<int>()
            .Where(i => i >= value)
            .Select(i => (Severity) i);
    }

    public enum Severity
    {
        All = 0,
        Trace = 1,
        Debug = 2,
        Information = 3,
        Warning = 4,
        Error = 5,
        Fatal = 6
    }
+2
source

, goto :

switch (severity.ToUpper())
{
  case "ALL":
    result.Add("ALL");
    goto case "DEBUG";
  case "DEBUG":
    result.Add("DEBUG");
    goto case "INFO";
  case "INFO":
    result.Add("INFO");
    goto case "WARN";
  case "WARN":
    result.Add("WARN");
    goto case "ERROR";
  case "ERROR":
    result.Add("ERROR");
    goto case "FATAL";
  case "FATAL":
    result.Add("FATAL");
    goto case "OFF";
  case "OFF":
    result.Add("OFF");
    break;
  default:
    break;
}
+1

goto:

        switch (severity.ToUpper())
        {
            case "ALL":
                result.Add("ALL");
                goto case "DEBUG";
            case "DEBUG":
                result.Add("DEBUG");
                goto case "INFO";
            case "INFO":
                result.Add("INFO");
                goto case "WARN";
            case "WARN":
                result.Add("WARN");
                goto case "ERROR";
            case "ERROR":
                result.Add("ERROR");
                goto case "FATAL";
            case "FATAL":
                result.Add("FATAL");
                goto case "OFF";
            case "OFF":
                result.Add("OFF");
                break;
            default:
                break;
        }

Microsoft (implicitly) recommends using this: http://msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx

+1
source

@nemesv Linq's answer is the best solution, but if you want to do it with a switch, you can do it and get the same result.

public static IEnumerable<string> SeverityOrHigher(string severity)
{
  var lastFound = -1;

  var severityList = new List<string>() { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
  var results = new List<string>();

  foreach (var t in severityList)
  {

    if (lastFound > -1)
    {
      for (var index = lastFound + 1; index < severityList.Count; index++)
      {
        results.Add(severityList[index]);
      }
      return results;
    }

    switch (severity.ToUpper())
    {
      case "ALL":
        results.Add(severity);
        lastFound = 0;
        break;
      case "DEBUG":
        lastFound = 1;
        results.Add(severity);
        break;
      case "INFO":
        lastFound = 2;
        results.Add(severity);
        break;
      case "WARN":
        lastFound = 3;
        results.Add(severity);
        break;
      case "ERROR":
        lastFound = 4;
        results.Add(severity);
        break;
      case "FATAL":
        lastFound = 5;
        results.Add(severity);
        break;
      case "OFF":
        lastFound = 6;
        results.Add(severity);
        break;
    }
  }

  return results;
}

Test:

  var list = SeverityOrHigher("ALL");
  foreach (var severity in list)
  {
    Console.WriteLine(severity);
  }

  Console.ReadKey();
+1
source

It doesn't look very pretty, but it can do the job for you:

string s = severity.ToUpper();
result.add("OFF");
if (s == "OFF")
  return result;
result.add("FATAL");
if (s == "FATAL")
  return result;
result.add("ERROR");
if (s == "ERROR")
  return result;
// ...
result.add("ALL");
return result;
0
source

I would try something like creating another list that represents all the valid degrees of severity and checks if the severity of the input is one of them:

public static IEnumerable<string> SeverityOrHigher(string severity)
{
    var result = new List<string>();
    var severities = new List<string> { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };

    severity = severity.ToUpper();

    if (severities.Contain(severity))
            result.Add(severity);

    return result;
}
0
source

All Articles