简体   繁体   中英

Refactoring two methods into one that have the same fields but different names

I have two event handlers that have the exact same code, except are handling different events. How can I go about combining these into using the same code without having to repeat myself?

static void SharePointEventHandler(object sender, SharePointEventArgs e)
{
    switch (e.ExceptionType)
    {
        case SharePointEventArgs.ExceptionLevel.Debug:
            CLog(LogType.Debug, e.Message);
            break;

        case SharePointEventArgs.ExceptionLevel.Info:
            CLog(LogType.Info, e.Message);
            break;

        case SharePointEventArgs.ExceptionLevel.Error:
            CLog(LogType.Error, e.Message, e.Exception);
            break;
    }
}

static void FTPEventHandler(object sender, FTPEventArgs e)
{
    switch (e.ExceptionType)
    {
        case FTPEventArgs.ExceptionLevel.Debug:
            CLog(LogType.Debug, e.Message);
            break;

        case FTPEventArgs.ExceptionLevel.Info:
            CLog(LogType.Info, e.Message);
            break;

        case FTPEventArgs.ExceptionLevel.Error:
            CLog(LogType.Error, e.Message, e.Exception);
            break;
    }
}

Depending the current state of the code, there are a variety of ways you could refactor this. I'm assuming that at the moment, the two EventArgs subclasses are not related at all. IMHO the best way to do this would be to change that. Specifically, create a base class from which both of the existing subclasses derive:

class ExceptionEventArgs : EventArgs
{
    public enum ExceptionLevel
    {
        Debug,
        Info,
        Error
    }

    public ExceptionLevel ExceptionType { get; set; }
    public string Message { get; set; }
    public Exception Exception { get; set; }
}

class SharePointEventArgs : ExceptionEventArgs { ... }
class FTPEventArgs : ExceptionEventArgs { ... }

Then you can use the same event handler for both events:

static void SharePointEventHandler(object sender, ExceptionEventArgs e)
{
    switch (e.ExceptionType)
    {
        case ExceptionEventArgs.ExceptionLevel.Debug:
            CLog(LogType.Debug, e.Message);
            break;

        case ExceptionEventArgs.ExceptionLevel.Info:
            CLog(LogType.Info, e.Message);
            break;

        case ExceptionEventArgs.ExceptionLevel.Error:
            CLog(LogType.Error, e.Message, e.Exception);
            break;
    }
}

This takes advantage of the variance support for .NET delegate types. A delegate instance can have as a target any method that receives parameters of the exact type specified for the delegate type, or which parameters which are assignable from those specified for the delegate type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM