C#重构if-else语句代码

本文关键字:代码 语句 if-else 重构 | 更新日期: 2023-09-27 18:30:05

请检查以下代码。。。

public enum LogType
{
    Debug,
    Info,
    Warn,
    Error,
    Fatal
}
private static readonly ILog log = 
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void LogError(LogType logtype, string message)
{
    XmlConfigurator.Configure();
    if (logtype == LogType.Debug)
        log.Debug(message);
    else if (logtype == LogType.Error)
        log.Error(message);
}

我不喜欢上面所有的if-else语句,并相信有一种更干净的方式来写这篇文章。我该如何重构它?日志类有不同的调试、错误等方法。

我想对一个方法进行一次调用,让它自动处理它。

LogMyError(LogType.Debug, "I am just logging here");

我怎么能做这样的事?我更喜欢远离switch语句。我正在寻找一个干净的面向对象的方法。

C#重构if-else语句代码

您的代码非常好;我不会改变它。

然而,如果你想更加"面向对象",思考一下你将如何这样做是很有启发性的。让我们只考虑你的两个案例;你可以很容易地看到它们将如何实现:

public abstract class LogType
{
    public static readonly LogType Debug = new LogTypeDebug();
    public static readonly LogType Error = new LogTypeError();
    private LogType() {} // Prevent anyone else from making one.
    public abstract void LogMessage(ILog logger, string message);
    private sealed class LogTypeDebug: LogType
    {
        public override void LogMessage(ILog logger, string message)
        {
            logger.Debug(message);
        }
    }
    private sealed class LogTypeError: LogType
    {
        public override void LogMessage(ILog logger, string message)
        {
            logger.Error(message);
        }
    }
}
...
//Obtain the log object the way you prefer.
private static readonly ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void LogError(LogType logtype, string message)
{
    logtype.LogMessage(log, message);
}

呼叫站点根本不会更改!它看起来仍然像:

LogError(LogType.Debug, "my message");

就这样:根本没有ifswitch语句!"切换类型"代码已被移动到虚拟函数表中,这是面向对象代码中的一部分。

此技术的一个很好的副作用是您永远不需要担心有人将整数强制转换为枚举类型的不受支持的值。LogType类型的变量的仅有可能值为null或对其中一个singleton的引用。

您可以使用Dictionary<LogType,Action<string>>来保存对每个枚举值执行的操作,然后只调用委托。

var logActions = new Dictionary<LogType,Action<string>>();
logActions.Add(LogType.Debug, log.Debug);
...
logActions[logtype](message);

更新:

如果您的if语句中只有少量分支,那么这就太过分了。对于5个以上这样的假设,我会使用这种方法。

Imo,没有任何明显的理由更改代码中的任何内容。功能清晰,明确了if/else的定义。函数声明允许您以希望使用它的方式使用它。

所以我不会更改代码中的任何内容。

祝你好运。

使用开关块:

switch (logtype)
{
    case LogType.Debug:
        log.Debug(message);
        break;
    case LogType.Error:
        log.Error(message);
        break;
    //more cases here as needed...
    default:
        throw new InvalidArgumentException("logtype");
}

总有switch语句:

switch (logtype)
{
    case LogType.Debug:
        log.Debug(message);
        break;
    case LogType.Error:
        log.Error(message);
        break;
    ....
}

您可以使用switch,也可以创建一个以LogType为键、以相应的LogXXXX方法为值的字典-一个Action<string>,然后执行

myDictionary[logType](message);