c# - 案例陈述的更好替代方案

标签 c# .net switch-statement

我目前有一个运行大约 300 行的 switch 语句。我知道这还没有达到极限,但我确信有更好的方法来处理这个问题。

switch 语句采用一个 Enum 来确定与日志记录相关的某些属性。现在的问题在于,很容易遗漏一个枚举值,并且它不会被赋予一个值,因为它不在 switch 语句中。

是否可以使用一个选项来确保使用每个枚举并为其提供完成其工作所需的一组自定义值?

编辑:


请求的代码示例:(这很简单,但准确说明了我的意思。还有一个枚举将存在以下值。)

internal void GenerateStatusLog(LogAction ActionToLog)
{
    switch (ActionToLog)
    {
        case LogAction.None:
            {
                return;
            }
        case LogAction.LogThis:
            {
                ActionText = "Logging this Information";
                LogText = "Go for it.";

                break;
            }
    }

    // .. Do everything else
}

最佳答案

编辑

我又想了想,看了SO里的相关问题,写了一些代码。我创建了一个名为 AdvancedSwitch<T> 的类,它允许您添加案例并公开一个方法来评估一个值,并允许您指定它应该检查是否存在的值。

这是我想出的:

public class AdvancedSwitch<T> where T : struct
{
    protected Dictionary<T, Action> handlers = new Dictionary<T, Action>();

    public void AddHandler(T caseValue, Action action)
    {
        handlers.Add(caseValue, action);
    }

    public void RemoveHandler(T caseValue)
    {
        handlers.Remove(caseValue);
    }

    public void ExecuteHandler(T actualValue)
    {
        ExecuteHandler(actualValue, Enumerable.Empty<T>());
    }

    public void ExecuteHandler(T actualValue, IEnumerable<T> ensureExistence)
    {
        foreach (var val in ensureExistence)
            if (!handlers.ContainsKey(val))
                throw new InvalidOperationException("The case " + val.ToString() + " is not handled.");

        handlers[actualValue]();
    }
}

您可以这样使用类:

public enum TrafficColor { Red, Yellow, Green }

public static void Main()
{
    Console.WriteLine("Choose a traffic color: red, yellow, green?");
    var color = (TrafficColor)Enum.Parse(typeof(TrafficColor), Console.ReadLine());
    var result = string.Empty;

    // Creating the "switch"
    var mySwitch = new AdvancedSwitch<TrafficColor>();

    // Adding a single case
    mySwitch.AddHandler(TrafficColor.Green, delegate
    {
        result = "You may pass.";
    });

    // Adding multiple cases with the same action
    Action redAndYellowDelegate = delegate
    {
        result = "You may not pass.";
    };
    mySwitch.AddHandler(TrafficColor.Red, redAndYellowDelegate);
    mySwitch.AddHandler(TrafficColor.Yellow, redAndYellowDelegate);

    // Evaluating it
    mySwitch.ExecuteHandler(color, (TrafficColor[])Enum.GetValues(typeof(TrafficColor)));

    Console.WriteLine(result);
}

通过创造性地使用匿名委托(delegate),您可以轻松地将新案例添加到您的“开关 block ”。 :)
并不是说您也可以使用 lambda 表达式和 lambda block ,例如 () => { ... }而不是 delegate { ... } .

您可以轻松地使用这个类来代替长长的 switch block 。

原帖:

如果您使用 Visual Studio,请始终创建 swich带有 switch 的语句代码片段。输入 switch按两次 Tab 键,它会自动为您生成所有可能性。

然后,添加一个default抛出异常的案例结束,这样在测试您的应用程序时,您会立即注意到有一个未处理的案例。

我的意思是这样的:

switch (something)
{
    ...
    case YourEnum.SomeValue:
        ...
        break;
    default:
        throw new InvalidOperationException("Default case reached.");
}

关于c# - 案例陈述的更好替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2880173/

相关文章:

.net - 创建两个数字的哈希码

c# - WebBrowser 打印设置

swift - 如何通过按其他按钮来更改一个按钮的图像?

javascript switch() 或 if()

与字符串指针混淆

c# - 为什么 WCF 服务能够处理来自不同进程的调用比来自线程的调用更多

c# - 如何通过 XML 中的 id 获取节点?

.net - 用于在 vb.net 和 vs2012 中解压缩 RAR 存档的 DLL 文件

c# - 在 C# .Net 中使用委托(delegate),当我用完 .Net 线程池中的线程时会发生什么情况?

javascript - 将数组传递给 Javascript 数组 C# ASP.NET