2013-10-16 79 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。 –