42

returnswitch caseステートメントを組み合わせるにはどうすればよいですか?

こんなもの欲しい

return switch(a)
       {
          case 1:"lalala"
          case 2:"blalbla"
          case 3:"lolollo"
          default:"default" 
       };

私はこの解決策について知っています

switch(a)
{
    case 1: return "lalala";
    case 2: return "blalbla";
    case 3: return "lolollo";
    default: return "default";
}

returnただし、演​​算子のみを使用したいと思います。

4

13 に答える 13

134

実際、これはC#8以降のswitch式を使用して可能です。

return a switch
    {
        1 => "lalala",
        2 => "blalbla",
        3 => "lolollo",
        _ => "default"
    };

式の切り替え

ここにはいくつかの構文の改善があります。

  • 変数はswitchキーワードの前にあります。順序が異なるため、switch式とswitchステートメントを視覚的に簡単に区別できます。
  • case要素と:要素は=>に置き換えられます。より簡潔で直感的です。
  • デフォルトのケースは_破棄に置き換えられます。
  • 本文は式であり、ステートメントではありません。

詳細と例については、MicrosoftのC#8WhatsNewを確認してください。

于 2019-09-06T09:56:41.840 に答える
26

:C#8(10年後!)の時点で、これが可能になりました。以下の回答を参照してください


switchステートメントであり、returnではないため、そのように組み合わせることができません(つまり、値を返しません)。 本当に1つだけを使用したい場合は、辞書を作成してスイッチ変数をマップして値を返すことができます。switch
return

var map = new Dictionary<int, string>() 
{
    {1, "lala"}, 
    {2, "lolo"}, 
    {3, "haha"}, 
};
string output;
return map.TryGetValue(a, out output) ? output : "default";
于 2010-07-26T11:06:39.040 に答える
22

私はこの解決策が最も簡単なものであると信じています、そしてあなたは間違いなくそれを使うべきです:

switch(a) { 
  case 1: return "lalala"; 
  case 2: return "blabla"; 
  case 3: return "lololo"; 
  default: return "default"; 
} 

しかし、あなたが1つを求めたのでreturn、あなたはこの少し流暢なクラスを使うことができました:

public class Switch<TElement, TResult> {
  TElement _element;
  TElement _currentCase;
  IDictionary<TElement, TResult> _map = new Dictionary<TElement, TResult>();

  public Switch(TElement element) { _element = element; }
  public Switch<TElement, TResult> Case(TElement element) {
    _currentCase = element;
    return this;
  }
  public Switch<TElement, TResult> Then(TResult result) {
    _map.Add(_currentCase, result);
    return this;
  }
  public TResult Default(TResult defaultResult) {
    TResult result;
    if (_map.TryGetValue(_element, out result)) {
      return result;
    }
    return defaultResult;
  }
}

このようなコードを作成するには:

  return new Switch<int, string>(a)
    .Case(1).Then("lalala")
    .Case(2).Then("blabla")
    .Case(3).Then("lololo")
    .Default("default");

残念ながら、型パラメーターはコンパイラーによって推測できず、少し不器用に感じます。Defaultは「スイッチ」の評価をトリガーし、チェーンの最後のメソッド呼び出しである必要があります。式に変換したため、常にデフォルト値が必要であることに注意してくださいswitch

更新:型推論の問題を解決し、次のコードを使用してユーザーに正しいことをさせることができます

public static class Switch {

  public static SwitchBuilder<TElement>.CaseBuilder On<TElement>(TElement element) {
    return new SwitchBuilder<TElement>(element).Start();
  }

  public class SwitchBuilder<TElement> {
    TElement _element;
    TElement _firstCase;
    internal SwitchBuilder(TElement element) { _element = element; }
    internal CaseBuilder Start() {
      return new CaseBuilder() { Switch = this };
    }
    private ThenBuilder Case(TElement element) {
      _firstCase = element;
      return new ThenBuilder() { Switch = this };
    }
    private SwitchBuilder<TElement, TResult>.CaseBuilder Then<TResult>(TResult result) {
      return new SwitchBuilder<TElement, TResult>(
        _element,
        _firstCase,
        result).Start();
    }
    public class CaseBuilder {
      internal SwitchBuilder<TElement> Switch { get; set; }
      public ThenBuilder Case(TElement element) {
        return Switch.Case(element);
      }
    }
    public class ThenBuilder {
      internal SwitchBuilder<TElement> Switch { get; set; }
      public SwitchBuilder<TElement, TResult>.CaseBuilder Then<TResult>(TResult result) {
        return Switch.Then(result);
      }
    }
  }

  public class SwitchBuilder<TElement, TResult> {
    TElement _element;
    TElement _currentCase;
    IDictionary<TElement, TResult> _map = new Dictionary<TElement, TResult>();
    internal SwitchBuilder(TElement element, TElement firstCase, TResult firstResult) {
      _element = element;
      _map.Add(firstCase, firstResult);
    }
    internal CaseBuilder Start() {
      return new CaseBuilder() { Switch = this };
    }
    private ThenBuilder Case(TElement element) {
      _currentCase = element;
      return new ThenBuilder() { Switch = this };
    }
    private CaseBuilder Then(TResult result) {
      _map.Add(_currentCase, result);
      return new CaseBuilder() { Switch = this };
    }
    private TResult Default(TResult defaultResult) {
      TResult result;
      if (_map.TryGetValue(_element, out result)) {
        return result;
      }
      return defaultResult;
    }
    public class CaseBuilder {
      internal SwitchBuilder<TElement, TResult> Switch { get; set; }
      public ThenBuilder Case(TElement element) {
        return Switch.Case(element);
      }
      public TResult Default(TResult defaultResult) {
        return Switch.Default(defaultResult);
      }
    }
    public class ThenBuilder {
      internal SwitchBuilder<TElement, TResult> Switch { get; set; }
      public CaseBuilder Then(TResult result) {
        return Switch.Then(result);
      }
    }
  }

}

その結果、この優れた、タイプセーフで流暢なインターフェースが実現します。ここで、各ステップでは、呼び出すメソッドの正しい選択しかありません(たとえばThen、後Case):

return Switch.On(a)
  .Case(1).Then("lalala")
  .Case(2).Then("blabla")
  .Case(3).Then("lololo")
  .Default("default");
于 2010-07-26T12:46:43.563 に答える
17

私は通常このようにします:

var result = null;

switch(a)
{
    case 1:
        result = "lalala";
        break;
    case 2:
        result = "blalbla";
        break;
    case 3:
        result = "lolollo";
        break;
    default:
        result = "default";
        break;
};

return result;
于 2010-07-26T11:22:10.483 に答える
11

新しいでは、との両方をC# 8組み合わせることができます。新しいものはとてもかわいいです。returnswitchswitch

public static RGBColor FromRainbow(Rainbow colorBand) =>
    colorBand switch
    {
        Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
        Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
        Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
        Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
        Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
        Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
        Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
        _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand))
    };

同等の古いスイッチは以下のとおりです。

public static RGBColor FromRainbowClassic(Rainbow colorBand)
{
    switch (colorBand)
    {
        case Rainbow.Red:
            return new RGBColor(0xFF, 0x00, 0x00);
        case Rainbow.Orange:
            return new RGBColor(0xFF, 0x7F, 0x00);
        case Rainbow.Yellow:
            return new RGBColor(0xFF, 0xFF, 0x00);
        case Rainbow.Green:
            return new RGBColor(0x00, 0xFF, 0x00);
        case Rainbow.Blue:
            return new RGBColor(0x00, 0x00, 0xFF);
        case Rainbow.Indigo:
            return new RGBColor(0x4B, 0x00, 0x82);
        case Rainbow.Violet:
            return new RGBColor(0x94, 0x00, 0xD3);
        default:
            throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
    };
}

この機能については、こちらをご覧ください。

于 2019-06-18T10:04:02.730 に答える
6
switch(a)
{
    case 1: return "lalala";
    case 2: return "blalbla";
    case 3: return "lolollo";
    default: return "default";
}
于 2010-07-26T10:56:14.183 に答える
6

これは私が考えることができる最も近いものです:

return    a==1 ? "lalala"
        : a==2 ? "blalbla"
        : a==3 ? "lolollo"
        : "default";
于 2010-09-08T20:19:55.857 に答える
4

私のマッピングソリューションはJordãoのソリューションのように見えますが、より柔軟で短いです。

return a
  .Map(1,"lalala")
  .Map(2,"blabla")
  .Map(3,"lololo")
  .Else(string.Empty);

両方の引数を関数にすることもできます。

return a
    .Map(x => x <= 0, "lalala")
    .Map(2, "blabla")
    .Map(x => x >= 3, x => "lololo" + x.ToString()); // lololo3 etc.
于 2013-07-22T18:41:04.677 に答える
3

私はあなたが望むことをするはずのNugetパッケージ( FluentSwitch )を作成しました。したがって、次のことができます。

var result = myValue.Switch()
    .When(1, "lalala")
    .When(2, "blalbla")
    .When(3, "lolollo")
    .Else("default")
    .Value();
于 2018-02-19T09:55:01.473 に答える
1

switchで値を返す場合は、delegateを使用できます。

int a = 2;
string result = new Func<string>(delegate ()
{
    switch (a)
    {
        case 1: return "lalala";
        case 2: return "blalbla";
        case 3: return "lolollo";
        default: return "default";
    }
})();

または:

int a = 2;
string result = new Func<int,string>(delegate (int i)
{
    switch (i)
    {
        case 1: return "lalala";
        case 2: return "blalbla";
        case 3: return "lolollo";
        default: return "default";
    }
})(a);

または、ラムダを使用します。

int a = 2;
string result = new Func<int,string>((int i) =>
{
    switch (i)
    {
        case 1: return "lalala";
        case 2: return "blalbla";
        case 3: return "lolollo";
        default: return "default";
    }
})(a);
于 2019-03-19T11:47:52.073 に答える
0
public String doStaff(int a) {

   switch(a)
       {
          case 1: return "lalala"
          case 2: return "blalbla"
          case 3: return "lolollo"
          default: return "default" 
       };
}
于 2010-07-26T10:56:03.077 に答える
0

スイッチ内に記述された条件から値を返す必要がある場合がある1つのユースケースがあります。まあ言ってみれば:

public void SomeMethod(SomeType enumType)  
{   
    switch (enumType)  
    {  
        case a:  
            if (condition)  
            {  
                if (condition1  && condition2)  
                {  
                    return true;  
                }  
            }  
            return false;  
            //break; break is actually not be required here if return used before break  
        case b:  
            if (condition)  
            {  
                if (condition3  && condition4)  
                {  
                    return true;  
                }  
            }  
            return false;  
            // break;  
        default:  
            return false;  
            //break;  
    }  

    Public enum SomeType  
    {  
        a,  
        b,  
        c,  
        d  
    }  
于 2013-06-05T02:34:26.220 に答える
0

他の人の応答の拡張として、意思決定にいくつかのパラメーターが含まれる場合は、リターンスイッチと一緒にタプルを使用することをお勧めします。この破棄との組み合わせは非常に強力です。

return (param1, param2, param3) switch
{
    (value1, value2, value3) => returnValue1,
    (value2, _, value3) => returnValue2
    (value3, _, _) => returnValue3

}

Microsoftによる別のサンプル: https ://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#tuple-patterns

于 2021-08-17T11:01:14.367 に答える