2013-10-16 50 views
2

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

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); 
    } 
} 
+5

接口可能比代表更好。 –

+0

这里没有明显的代表需要。关于代表的文章将会有例子。 –

+0

你能否给我提供一个可以使用委托的简单例子? – Angad

回答

1

的代表们是有用的好例子是LINQevent handlers。例如,你可以重新实现LINQ的SelectWhere方法,像这样:

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可能会更有意义。例如。

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方法,您可以使用explicit interface implementation让它暴露本身既是​​和static方法:

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(); 
} 
+0

您能否提供一个简单的委托示例,必须使用委托的场景? – Angad

+0

@ user1108205 LINQ和事件处理程序是代表非常有用的两个很好的示例。我在答案的顶部添加了一个示例。有关类似问题,请参阅http://stackoverflow.com/questions/19405571/failed-to-understand-the-use-of-delegates-in-real-world-scenarios。 –