簡體   English   中英

C# - 在默認情況下獲取開關值

[英]C# - Get switch value if in default case

請幫忙,我有這個案例:

switch(MyFoo()){
    case 0: //...
        break;
    case 1: //...
        break;
    case 2: //...
        break;
    default:
        // <HERE>
        break;
}

如您所見,開關直接從方法中獲取值,而不將其保存為變量。

是否有可能獲得哪個值觸發default情況? 例如,如果MyFoo()返回 7,我如何獲得該值?

我想避免將方法結果保存為變量,有沒有辦法從案例內部獲取開關值? 像這樣的東西:

default:
    this.SwitchValue // <<--
    break;

感謝您的閱讀~Saba

有沒有辦法從案例內部獲取開關值?

唯一(正確)的方法實際上是將MyFoo()的結果存儲在一個變量中。

var fooResult = MyFoo();
switch (fooResult)
{
    case 0:
        ...
        break;
    ...
    default:
        handleOthersCase(fooResult);
        break;
}

這段代碼可讀且易於理解,並且沒有額外成本(正如@SheldonNeilson 所說:無論如何它都在堆棧中)。

此外,關於交換機的 MSDN 第一個例子完全是這樣的。 您還可以在語言規范中找到信息。

您也可以根據 字典制作自己的開關,但我看到的唯一優點是您可以將它用於復雜情況(任何類型的對象而不是 string/int/...)。 性能是一個缺點。

它可能看起來像這樣:

public class MySwitch<T> : Dictionary<T, Action<T>>
{
    private Action<T> _defaultAction;

    public void TryInvoke(T value)
    {
        Action<T> action;
        if (TryGetValue(value, out action))
        {
            action(value);
        }
        else
        {
            var defaultAction = _defaultAction;
            if (defaultAction != null)
            {
                defaultAction(value);
            }
        }
    }

    public void SetDefault(Action<T> defaultAction)
    {
        _defaultAction = defaultAction;
    }
}

並像這樣使用:

var mySwitch = new MySwitch<int>();

mySwitch.Add(1, i => Console.WriteLine("one"));                             // print "one"
mySwitch.Add(2, i => Console.WriteLine("two"));                             // print "two"
mySwitch.SetDefault(i => Console.WriteLine("With the digits: {0}", i));     // print any other value with digits.

mySwitch.TryInvoke(42);                                                     // Output: "With the digits: 42"

或者基於這個響應,這個:

public class MySwitch2<T>
{
    private readonly T _input;

    private bool _done = false;

    private MySwitch2(T input)
    {
        _input = input;
    }

    public MySwitch2<T> On(T input)
    {
        return new MySwitch2<T>(input);
    }

    public MySwitch2<T> Case(T caseValue, Action<T> action)
    {
        if (!_done && Equals(_input, caseValue))
        {
            _done = true;
            action(_input);
        }
        return this;
    }

    public void Default(Action<T> action)
    {
        if (!_done)
        {
            action(_input);
        }
    }
}

可以這樣使用:

MySwitch2<int>.On(42)
    .Case(1, i => Console.WriteLine("one"))
    .Case(2, i => Console.WriteLine("two"))
    .Default(i => Console.WriteLine("With the digits: {0}", i));

我也看不出為什么要這樣使用它的原因,但可能是一種解決方法,如下所示:

int x;
switch ( x = MyFoo())
{
    case 0: //...
        break;
    case 1: //...
        break;
    case 2: //...
        break;
    default:
        var s = x; // Access and play with x here
        break;
}

不,這是不可能的。 如果您想看起來像重新發明輪子,您可以將值分配給 switch 內部的變量:

        int b;
        .....
        switch (b = MyFoo())
        {
            case 1:
                break;
            case 2:
                break;
            default:
                //do smth with b
                break;
        }

最簡單的方法是將MyFoo()的結果保存為一個變量。但如果你不想這樣做,你可以這樣做:

switch(MyFoo()){
    case 0: //...
        break;
    case 1: //...
        break;
    case 2: //...
        break;
    default:
        this.SwitchCase = MyFoo();
        break;
}

盡管我建議不要這樣做,並說將值保存為變量以節省程序的額外工作。

示例越復雜,將MyFoo的值保存為變量變得越重要,因為MyFoo的值可能在 switch 和 default 情況之間發生了變化。

此外,這只適用於MyFoo沒有副作用的情況,並且顯然必須始終為任何給定參數返回相同的值。

例如下面的工作:

Private int MyFoo()
{
   return 3;
}

但以下不會:

private int MyFoo()
{
  Random r = new Random();
  return r.Next(5);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM