2

我有一个代码片段,如下所示。我如何重构它以使用委托?是否值得重新编写此代码以使用委托?我认为这是可以使用代表的场景我错了吗?我正在尝试学习代表并希望看到它们的使用。

public class Program
{
    public static void Main(string[] args)
    {             
        var count = Int32.Parse(Console.ReadLine());
        Console.Write("Logger Type -->");
        var logType = Console.ReadLine();

        if (logType == "A")
        {
            if (count > 10)
            {
                LoggerTypeA.Error(count);
            }
            else
            {
                LoggerTypeA.Warning(count);
            }
        }
        else
        {
            if (count > 10)
            {
                LoggerTypeB.Error(count);
            }
            else
            {
                LoggerTypeB.Warning(count);
            }
        }

        Console.ReadLine();

    }
}

internal static class LoggerTypeA
{
    public static void Error(int count)
    {
        Console.WriteLine("Error {0} from Logger A", count);
    }

    public static void Warning(int counter)
    {
        Console.WriteLine("Warning {0} from Logger A", counter);
    }
}

internal static class LoggerTypeB
{
    public static void Error(int count)
    {
        Console.WriteLine("Error {0} from Logger B", count);
    }

    public static void Warning(int counter)
    {
        Console.WriteLine("Warning {0} from Logger ", counter);
    }
}
4

1 回答 1

1

委托有用的很好的例子是LINQ事件处理程序。例如,您可以像这样重新实现 LINQSelectWhere方法:

public static IEnumerable<TResult> MySelect<TSource, TResult>
              (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
    foreach (var item in source)
        yield return selector(item);
}
public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> source,
                                        Func<T, bool> selector)
{
    foreach (T item in source)
        if (selector(item))
            yield return item;
}

然后使用 lambda 语法,您可以轻松创建执行操作的方法,例如myList.MyWhere(x => x.Name == "John").

interface在这种情况下使用 an 可能更有意义。例如

public static void Main()
{
    var count = Int32.Parse(Console.ReadLine());
    Console.Write("Logger Type -->");
    var logType = Console.ReadLine();
    ILogger logger = logType == "A" ? (ILogger)new LoggerTypeA() : new LoggerTypeB();
    if (count > 10)
    {
        logger.Error(count);
    }
    else
    {
        logger.Warning(count);
    }

    Console.ReadLine();
}
public interface ILogger
{
    void Error(int count);
    void Warning(int count);
}
internal class LoggerTypeA : ILogger
{
    public void Error(int count)
    {
        Console.WriteLine("Error {0} from Logger A", count);
    }

    public void Warning(int count)
    {
        Console.WriteLine("Warning {0} from Logger A", count);
    }
}

internal class LoggerTypeB : ILogger
{
    public void Error(int count)
    {
        Console.WriteLine("Error {0} from Logger B", count);
    }

    public void Warning(int count)
    {
        Console.WriteLine("Warning {0} from Logger ", count);
    }
}

如果您仍然希望能够将记录器用作static方法,则可以使用显式接口实现来使其自身暴露为 anILoggerstatic方法:

internal class LoggerTypeA : ILogger
{
    public static void Error(int count)
    {
        Console.WriteLine("Error {0} from Logger A", count);
    }
    void ILogger.Error(int count)
    {
        Error(count);
    }

    public static void Warning(int count)
    {
        Console.WriteLine("Warning {0} from Logger A", count);
    }
    void ILogger.Warning(int count)
    {
        Warning(count);
    }
}

例如有了这个,以前的代码仍然有效,但你也可以这样做LoggerTypeA.Error(count);

可以使用代表完成的方法如下。如您所见,与您的原始方法相比没有太大改进。

{
    var count = Int32.Parse(Console.ReadLine());
    Console.Write("Logger Type -->");
    var logType = Console.ReadLine();
    Action<int> logAction;
    if (logType == "A")
    {
        if (count > 10)
        {
            logAction = LoggerTypeA.Error;
        }
        else
        {
            logAction = LoggerTypeA.Warning;
        }
    }
    else
    {
        if (count > 10)
        {
            logAction = LoggerTypeB.Error;
        }
        else
        {
            logAction = LoggerTypeB.Warning;
        }
    }
    logAction(count);

    Console.ReadLine();
}
于 2013-10-16T14:07:22.603 回答