C#中的内联开关/ case语句

时间:2010-08-05 14:50:07

标签: c# switch-statement

我很奇怪看到我可以制作代码的行数很少。有没有办法将其压缩为内联案例陈述?

    switch (FIZZBUZZ)
    {
      case "Fizz":
        {
          //Do one process
          break;
        }
      case "Buzz":
        {
          //Do one process
          break;
        }
      case "FizzBuzz":
        {
          //Do one process
          break;
        }
    }

看起来像这样:

    switch (FIZZBUZZ)
    {
      case "Fizz": //Do one process
      case "Buzz": //Do one process
      case "FizzBuzz": //Do one process
    }

13 个答案:

答案 0 :(得分:17)

如果你想压缩事情,你可以把事情放在一条线上(让我们想象“做一个过程是对Console.WriteLine的调用):

switch (FIZZBUZZ)
{
    case "Fizz": Console.WriteLine("Fizz"); break;
    case "Buzz": Console.WriteLine("Buzz"); break;
    case "FizzBuzz": Console.WriteLine("FizzBuzz"); break;
}

如果你想获得幻想,你可以创建一个字符串映射到这样的动作:

var map = new Dictionary<String, Action>
{
    { "Fizz", () => Console.WriteLine("Fizz") },
    { "Buzz", () => Console.WriteLine("Fizz") },
    { "FizzBuzz", () => Console.WriteLine("FizzBuzz") }
};

然后你可以调用这样的方法:

map[FIZZBUZZ].Invoke(); // or this: map[FIZZBUZZ]();

答案 1 :(得分:10)

仅供参考,如果有人在寻找内联速记切换案例陈述以返回值,我发现对我来说最好的解决方案是多次使用三元运算符:

string Season = "Spring";
Season = Season == "Fall" ? "Spring" : Season == "Spring" ? "Summer" : "Fall";

通过将其包装在parens中,您可以选择使其在内联时更具可读性:

Season = (Season == "Fall" ? "Spring" : (Season == "Spring" ? "Summer" : "Fall"));

或使用多行并缩进:

Season = Season == "Fall" ? "Spring" 
       : Season == "Spring" ? "Summer" 
       : "Fall";

因此,要编写代码执行块,您可以编写:

string FizzBuzz = "Fizz";
FizzBuzz = FizzBuzz == "Fizz" ? MethodThatReturnsAString("Fizz") : (FizzBuzz == "Buzz" ? MethodThatReturnsAString("Buzz") : MethodThatReturnsAString("FizzBuzz"));

对于很长的case元素列表来说,这不是最值得尊敬的解决方案,但是你正在尝试进行内联切换语句;)

来自社区的批评?

答案 2 :(得分:8)

假设这纯粹是深奥的,并且你不会想在生产系统中使用它,你可能会滥用表达式树:

FIZZBUZZ.Switch(Fizz => DoSomething(),
                Buzz => DoSomethingElse(),
                FizzBuzz => DoSomethingElseStill());

Switch是一种扩展方法:

public static void Switch(this string @this, params Expression<Action>[] cases)
{
    Expression<Action> matchingAction = cases.SingleOrDefault(@case => @case.Parameters[0].Name == @this);
    if (matchingAction == null) return; // no matching action

    matchingAction.Compile()();
}

答案 3 :(得分:1)

你总是要有一个休息声明,以便离开交换机而不是你提到的那样

  switch (FIZZBUZZ)
    {
      case "Fizz": /*Do one process*/break;
      case "Buzz": /*Do one process*/break;
      case "FizzBuzz": /*Do one process*/break;
    }

答案 4 :(得分:1)

如果您对最少的代码感兴趣,那么您可以写下:

switch (FIZZBUZZ) { case "Fizz": /* Do one process */ break; case "Buzz": /* Do one process */ break; case "FizzBuzz": /* Do one process */ break; }

我不会推荐它。

很难确切地说出你在问什么 - 你是试图在案件之间摔倒,还是只是删除大括号?

答案 5 :(得分:1)

在C#8中,您可以执行以下操作

    public Form1()
    {
        InitializeComponent();
        Console.WriteLine(GetSomeString("Fizz"));
    }

    public static string GetSomeString(string FIZZBUZZ) =>
       FIZZBUZZ switch
       {
           "Fizz" => "this is Fizz",
           "Buzz" => "this is Buzz",
           "FizzBuzz" => "this is FizzBuzz",
           _ => "Unknown"
       };

这等效于

    public static string GetSomeString(string FIZZBUZZ)
    {
        switch (FIZZBUZZ)
        {
            case "Fizz": return "this is Fizz";
            case "Buzz": return "this is Buzz";
            case "FizzBuzz": return "this is FizzBuzz";
            default: return "Unknown";
        }
    }

答案 6 :(得分:0)

一个简单的方法是:

switch (FIZZBUZZ)
{
     case "Fizz": Console.WriteLine("Fizz"); break;
     case "Buzz": Console.WriteLine("Buzz"); break;
     case "FizzBuzz": Console.WriteLine("FizzBuzz"); break;
}

每个只有一行。但每行有多个陈述......

答案 7 :(得分:0)

我不知道有什么方法可以做到这一点,同时保持一些可读性,除了明显的:

switch (FIZZBUZZ) 
    { 
      case "Fizz": { //Do one process } break;
      case "Buzz": { //Do one process  } break;
      case "FizzBuzz": { //Do one process  } break;
    }

答案 8 :(得分:0)

您可以使用C#将任意数量的代码放在一行上。

安德鲁说。

我个人喜欢留下空格,因为它可以更容易地阅读代码,但是我再次成为唯一一个评论他的代码或编写方法和函数足够小以便能够快速扫描代码以查看的代码它能做什么。 :)

答案 9 :(得分:0)

您不需要case语句的花括号,但是对于每种情况都需要break语句。否则,你真的不能做太多的事情

答案 10 :(得分:0)

  

死灵法师的海报在这里

因此,我将此视为挑战。我没有对“仅使用Switch..Case语法”语句做出通常的回答,而是对技能和知识进行了编码挑战(并不是我两者都有很多)。

设置

使用

public enum FizzBuzz {
    Fizz,
    Buzz,
    FizzBuzz
}

public static class EnumExtension {
    public static void SwitchCase ( this FizzBuzz enm , params KeyValuePair<FizzBuzz , Action> [] parms ) {
        foreach ( var kvp in parms ) {
            if ( kvp.Key == enm ) {
                kvp.Value();
            }
        }
    }
}

实施

public class Program {
    static void Main ( string [] args ) {
        var enm = FizzBuzz.Fizz;

        ProcessEnum( enm );
    }

    public static void ProcessEnum ( FizzBuzz enm ) {
        enm.SwitchCase(
            new KeyValuePair<FizzBuzz , Action>( FizzBuzz.Fizz , FizzMethod ) ,
            new KeyValuePair<FizzBuzz , Action>( FizzBuzz.Buzz , BuzzMethod ) ,
            new KeyValuePair<FizzBuzz , Action>( FizzBuzz.FizzBuzz , FizzBuzzMethod )
            );
    }

    private static void FizzMethod () {
        System.Console.WriteLine( "" );
    }
    private static void BuzzMethod () {
        System.Console.WriteLine( "" );
    }
    private static void FizzBuzzMethod () {
        System.Console.WriteLine( "" );
    }

}

答案 11 :(得分:0)

一个挑战是使用C#8 switch expressions

问题在于每个分支的主体是一个表达式,而不是一组语句。

您可以通过使每个分支返回一个Action对象来解决此问题。

请注意语法:如果我将任何一个表达式显式转换为Action类型,则编译器将隐式转换其他每个表达式。我选择转换最后一个(默认)表达式。

public static void Performction(string input) =>
    (
        (input) switch 
        {   
            "FIZZ" => () => Console.WriteLine("This is the fizz"),
            "BUZZ" => () => Console.WriteLine("This is the buzz"),
            "FIZZBUZZ" => () => 
                {
                    Console.WriteLine("This is a Fizz");
                    Console.WriteLine("But it is a buzz as well!");
                },
            _ => new Action(() => {})
        }
    )();

答案 12 :(得分:0)

在C#8中引入。

您现在可以执行以下切换操作:

FIZZBUZZ switch
{
    "fizz"     => /*do something*/,
    "fuzz"     => /*do something*/,
    "FizzBuzz" => /*do something*/,
    _ => throw new Exception("Oh ooh")
};

分配可以这样完成:

string FIZZBUZZ = "fizz";
string result = FIZZBUZZ switch
    {
        "fizz"     => "this is fizz",
        "fuzz"     => "this is fuzz",
        "FizzBuzz" => "this is FizzBuzz",
        _ => throw new Exception("Oh ooh")
    };
Console.WriteLine($"{ result }"); // this is fizz

函数调用:

public string Fizzer()     => "this is fizz";
public string Fuzzer()     => "this is fuzz";
public string FizzBuzzer() => "this is FizzBuzz";
...
string FIZZBUZZ = "fizz";

string result = FIZZBUZZ switch
    {
        "fizz"     => Fizzer(),
        "fuzz"     => Fuzzer(),
        "FizzBuzz" => FizzBuzzer(),
        _ => throw new Exception("Oh ooh")
    };
Console.WriteLine($"{ result }"); // this is fizz

您可以在此处了解有关新开关盒的更多信息:What's new in C# 8.0