繁体   English   中英

C# 中的内联 switch / case 语句

[英]Inline switch / case statement in C#

我很奇怪地看到我可以编写多少行代码。 有没有办法将其压缩为内联 case 语句?

    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
    }

在 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

每个案例有多个内联操作(我认为必须有代表):

string FIZZBUZZ = "fizz";
string result = String.Empty;

_= (FIZZBUZZ switch
{
    "fizz" => () =>
    {
        Console.WriteLine("fizz");
        result = "fizz";
    },
    "fuzz" => () =>
    {
        Console.WriteLine("fuzz");
        result = "fuzz";
    },
    _ => new Action(() => { })
});

您可以在此处阅读有关新开关案例的更多信息: C# 8.0 中的新增功能

如果你想压缩一些东西,你可以把东西放在一行上(让我们想象一下“做一个过程就是调用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]();

仅供参考,如果有人正在寻找内联速记 switch case 语句来返回值,我发现对我来说最好的解决方案是多次使用三元运算符:

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

您可以选择将其包装在括号中,使其更具可读性,同时仍内联:

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 元素来说,这不是最受人尊敬的解决方案,但您正在尝试执行内联 switch 语句;)

来自社区的批评?

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

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()();
}

在 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";
        }
    }

你总是必须有一个 break 语句才能离开 switch,而不是你可以像你提到的那样做

  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 */ break; case "Buzz": /* Do one process */ break; case "FizzBuzz": /* Do one process */ break; }

我不会推荐它。

很难确切地说出你在问什么——你是想在案例之间失败,还是只是去掉大括号?

那么一个简单的方法是:

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

每个只有一行。 但是每行有多个语句......

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

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

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

正如安德鲁所说。

就我个人而言,我的偏好是留下空白,因为它可以让代码更容易阅读,但我是这里唯一一个评论他的代码或编写足够小的方法和函数的开发人员,以便能够快速扫描代码以准确查看它的作用. :)

case 语句不需要花括号,但是每个 case 都需要一个 break 语句。 否则,你真的做不了多少

死灵法师海报在这里

所以我把这当作一个挑战。 与通常的“只使用 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( "" );
    }

}

一个挑战是使用C#8 switch 表达式

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

您可以通过使每个分支返回一个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(() => {})
        }
    )();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM