我目前有一个运行大约 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/