5

考虑这段代码:

if (results.Contains(14))
{
    //anything
}
else if (results.Contains(15))
{
    //anything
}
else if (results.Contains(16))
{
    //anything
}

我想用 switch case 编写这段代码:

switch (results)
{
    case results.Contains(14):
}

但是我们不能在 C# 中编写它。

什么是编写上述代码的明确方法,知道这results是一个long[]

4

9 回答 9

8

这有什么问题:

if (results.Contains(14) || results.Contains(15) || results.Contains(16))
{
  new Exception("anything");
}
于 2013-08-13T13:05:06.807 回答
4

你真正想做什么?

以下应该有效,但我不确定这是否是您的想法:

int[] values = {14, 15, 16};
foreach (var n in values) {
  if(result.Contains(n)) 
     throw new Exception(n.ToString()) 
}

-- 编辑:问题发生了很大变化,所以这里有一个更新 --

我可能会使用 plainif-else但如果你有很多选项或复杂的逻辑(例如不仅仅是results.Contains()),有时最好选择表:

int[] results = {13, 14, 15};
action_map = new Dictionary<int, Action>();
action_map[14] = () => Console.Out.WriteLine("14");
action_map[15] = () => Console.Out.WriteLine("15");
action_map[16] = () => { throw new InvalidOperationException(); };
action_map[0] = () => {}; // NOP, default case - executed if no match found

var action_key = dict.Keys.FirstOrDefault(k => results.Contains(k));
action_map[action_key]();

在实际代码中,我可能会将其包装到一个类中:

var table = new FnTable();
table.Add(14, () => Console.Out.WriteLine("14"));
table.Add(15, () => Console.Out.WriteLine("15"));
table.Add(16, () => { throw new InvalidOperationException(); });

int[] results = {13, 14, 15};
table.ExecuteFirstFrom(results);
于 2013-08-13T13:12:58.183 回答
4

因为它可能在一个具有第一解决方案的字符串中,那就是使用正则表达式。

var m = System.Text.RegularExpressions.Regex.Matches(results, @"\d{1,2}")[0];
throw new Exception(m);

(注意:我是在记事本中完成的,因此可能需要稍作调整)

您可能不得不使用匹配语法,因为这仅适用于 1-2 数字。在一个字符串中。

于 2013-08-13T13:06:04.307 回答
3

我喜欢使用动作词典的方法

        var swticher = new Dictionary<long, Func<Exception>>()
        {
            {15,()=>new Exception("15")},
            {14,()=>new Exception("14")}
        };

        throw swticher[14].Invoke();

当然,更复杂的例子将展示这种方法的力量:)

为什么使用字典而不是开关:https ://stackoverflow.com/a/11617459/1714342

抽象的:

简短的回答是 switch 语句以线性方式执行,而字典以对数方式执行。

于 2013-08-13T13:05:23.473 回答
3

通常替换 if/switch 语句的明确方法是使用多态性。但是,在示例中,您提供的 if 语句非常简单,可以用计算异常内容的简单算法替换它们,如 Robert Snyder 的回答中所述。

于 2013-08-13T13:10:23.960 回答
2

开关(C# 参考)

Each case label specifies a constant value.

在您预期的示例代码中,results.Contains(14)不是一个常量值,因此语法将无效。

于 2013-08-13T13:12:49.443 回答
2

我实际上不建议这样做,但如果你真的很喜欢switch 语句......

long? CheckSpecialNumbers(long[] res)
{
    var specialNumbers = new List<long>() {14, 15, 16};
    var inters= specialNumbers.Intersect(res);
    return inters.Count() > 0 ? (long?)inters.First() : null;
}

那么你可以这样做:

long? res = CheckSpecialNumbers(results);

switch (res)
{
    case 14:
        Console.WriteLine(14);
        break;
    case 15:
        Console.WriteLine(15);
        break;
    case 16:
        Console.WriteLine(16);
        break;
}
于 2013-08-13T13:29:05.750 回答
2

您可以switch在 a 中使用语句foreach

long[] results = new long[] { 15, 14, 16 };
foreach (long v in results)
{
    switch (v)
    {
        case 14:
            // anything
            break;
        case 15:
            // anything
            break;
        case 16:
            // anything
            break;
    }
}

为了更好地匹配您的问题,您应该首先订购数组并在匹配后退出 foreach:

long[] results = new long[] { 15, 14, 16 };
Array.Sort(results);
foreach (long v in results)
{
    switch (v)
    {
        case 14:
            // anything
            break;
        case 15:
            // anything
            break;
        case 16:
            // anything
            break;
        default:
            continue; // continue the foreach loop
    }
    break; // break the foreach loop because we had a valid match
}
于 2013-08-13T13:14:41.407 回答
1

我想用开关盒写这段代码

A switch- casestatement 用于根据给定变量的值分支执行路径。OP希望根据布尔表达式的值进行分支,具体来说,是的返回值Contains。这只能使用if-else语句来完成。写作switch (results)没有意义,因为results它是一个整数数组。

于 2013-08-13T13:18:22.997 回答