2016-10-07 27 views
0

我想轉換的(這是很容易出錯)....通型的類型,而不是字符串paramater

public static void GenerateReport(string report) 
    { 
     switch (report) 
     { 
      case "ReportA": 
       // do stuff 
       break; 
      case "ReportB": 
       // do stuff 
       break; 
      case "ReportC": 
       // do stuff 
       break; 
     } 
    } 

對此....

public static void GenerateReport<T>() 
    { 
     switch (T) // BUT.... how do I handle this? 
     { 
      case ReportA: 
       // do stuff 
       break; 
      case ReportB: 
       // do stuff 
       break; 
      case ReportC: 
       // do stuff 
       break; 
     } 
    } 

我所看到的很多問題都詢問差不多是同樣的事情,但他們都沒有讓我回答。像this one,但對我而言,該線程提供的解決方案不起作用。當我嘗試編譯時會引發多個語法錯誤。該解決方案有云:

switch typeof(T) { 
    // 
} 
+3

使有問題的類型處理「做東西」部分。基本上把你的'switch'改成OOP設計。 – juharr

+1

不知道我關注 –

+1

這基本上是多態。創建一個具有'GenerateReport()'方法的抽象'Report'類。 – Amy

回答

1

無論何時如果/ switch語句中的代碼將根據輸入執行不同的操作,但會生成類似於您的問題的通用輸出,通常表示您需要考慮進行一些重構。

在這種情況下,最好的選擇是使用基於接口的設計,並將執行各種報告的邏輯移動到它們自己的類型中。這將允許您根據需要更好地管理其他報告,而無需觸摸現有代碼。

public interface IReporter { 
    void GenerateReport(); 
} 

public class ReporterA : IReporter { 
    public void GenerateReport() { /* execute report */} 
} 
public class ReporterB : IReporter { 
    public void GenerateReport() { /* execute report */} 
} 
public class ReporterC : IReporter { 
    public void GenerateReport() { /* execute report */} 
} 

// The responsibilty of the factory is only to create the correct reporter based on the request 
public class ReporterFactory{ 
    public IReporter CreateReporter(string input){ 
     /* the logic here can vary, you can get creative with Attributes 
      and name each report type and use reflection to create the 
      correct report type. You can also use an Enum and use that as an attribute value over 
      each Reporter type. There are many ways to handle it. 
     */ 
    } 
} 

/* your refactored method */ 
public static void GenerateReport(string report) 
{ 
    /* again, creation pattern could be based on something other than a string. It depends on how you want to differentiate your reporters*/ 
    var reporter = new ReporterFactory().CreateReporter(report); 
    reporter.GenerateReport(); 
} 
+1

好的,謝謝。這使得重構變成了一個比我想象的更大的項目,但是我可以看到這是完成這項工作的最佳方式,以便將來擴展。我會一路上遇到一些問題,但我會在一個單獨的線程中發佈它們。 –

1

泛型關鍵的一點是,如果你正在做的事情是不是大致爲每個最終T相同,那麼它實際上不是通用和你不應該那樣做。

好這裏的候選人可能包括:

  • 枚舉
  • 多態性(一virtual/abstract法)
  • 傳遞一個Type實例

但......不是仿製藥。語言不能幫助你的原因是因爲這不合適。這就是說:你可以這樣做:

if(typeof(T) == typeof(Foo)) { 
    // foo 
} else if (typeof(T) == typeof(Bar)) { 
    // bar 
} ... 

但是;這有點兒缺乏泛型。

3

你不需要爲仿製藥,也不能與類型檢測switch語句...而不是使用方法重載爲每個類型,並保持做的東西件在自己的方法......

public static void GenerateReport(ReportA a) { /*do stuff*/ } 
public static void GenerateReport(ReportB b) { /*do stuff*/ } 
public static void GenerateReport(ReportC c) { /*do stuff*/ } 
0

你可以這樣說:

public static void RunIfEqual<TLeft, TRight>(Action action) 
    { 
     if (typeof(TLeft) == typeof(TRight)) 
     { 
      action(); 
     } 
    } 

    ... 

    RunIfEqual<T, ReportA>(()=> ...); 
    RunIfEqual<T, ReportB>(()=> ...); 
    RunIfEqual<T, ReportC>(()=> ...); 

甚至更​​好的方法,你可以定義一些ReportGeneratorFactory,將選擇使用這個典型,其發電機並將它還給你。然後你可以撥打GenerateReport就可以了。

相關問題