2009-04-28 173 views
0

我有一個稱爲CheckDuration的重載實用程序方法,它具有以下功能簽名。你可以聲明一個可變長度的泛型類型聲明嗎?

private static Action<int> CheckDuration(Action action) 
    private static Action<int> CheckDuration<T>(Action<T> action, T arg) 

基本上CheckDuration在控制檯上打印需要多長時間才能運行方法。

現在,我想檢查一個方法的持續時間,其中需要2個參數。
所以我將不得不創建另一個重載CheckDuration與以下方法簽名。

private static Action<int> CheckDuration<T, U>(
     Action<T, U> action, T arg1, U arg2) 

有沒有辦法更好地處理這個問題?
我在思考着什麼樣

private static Action<int> CheckDuration<params T>(
     Action<params T> action, params T arg) 

,這顯然是行不通的。

[UPDATE]我現在將留下這個問題,看看是否有人提出瞭解決這類問題的方法。

回答

5

不幸的是,你已經是一樣乾淨,因爲它會得到。 C#不支持對通用類型參數使用params,並且支持類似的東西將非常困難。您的原始解決方案非常好,並且與BCL中類似的代表類似,Action委託人具有超載的定義,以採用不同數量的參數。

+0

出於好奇,你能告訴我爲什麼這會很困難嗎?我只是好奇:) – 2009-04-28 17:34:03

0

不,沒有辦法。不過,我想這個'CheckDuration'可以工作,TU都應該實現一些定義良好的接口或者從一個基類繼承(否則你會做很多反射,這會破壞使用的目的仿製藥)。因此,可以考慮:

Action<int> CheckDuration<T>(Action<T> action, params T[] args) 
    where T : ISupportCheckDuration 

你就可以任何東西這是ISupportCheckDuration兼容在那裏。

+0

不幸的是,在這個例子中,你不得不擁有一種類型,因爲所有的參數都是T類型的。 – 2009-04-28 15:07:05

+0

不,他們都應該實現ISupportCheckForDuration或其他。只要滿足這種條件,這些可以是完全不同的類型。 – 2009-04-28 15:09:41

+0

Anton Goglev:我在考慮傳遞「Console.WriteLine」,但由於它期望「params object []」,因此我無法使用它。 – Sung 2009-04-28 15:13:17

0

看一看PostSharp:

http://www.postsharp.org/

我認爲它可以幫助你。看看跟蹤示例。我認爲你可以適應它來執行你的時間。然後,無論參數的數量如何,您都可以將屬性添加到需要時間的任何方法中。

克里斯

3

很喜歡你想要的,但你可以達到同樣的目標你不能做到這一點:

public static class MethodTimer 
{ 
    public static long Run(Action action) 
    { 
     var sw = System.Diagnostics.Stopwatch.StartNew(); 
     action(); 
     sw.Stop(); 
     return sw.ElapsedMilliseconds; 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     long time = MethodTimer.Run(() => File.Open(@"c:\test.txt", 
      FileMode.CreateNew)); 
     Console.WriteLine(time); 
     Console.ReadLine(); 
    } 
} 

你甚至可以將此定義爲一個擴展方法使你的代碼可能是:

 Action act =() => File.Open(@"c:\test.txt", FileMode.CreateNew); 
     time=act.Time(); 

此方法將被定義爲:

public static class MethodTimer 
    { 
     public static long Time(this Action action) 
     { 
      var sw = System.Diagnostics.Stopwatch.StartNew(); 
      action(); 
      sw.Stop(); 
      return sw.ElapsedMilliseconds; 
     } 
    } 

編輯

你並不需要定義這種方法是利用各地要時間的方法封閉的任何新方法。所以:

MethodTimer.Time(()=> File.Open("",FileMode.Open); 
MethodTimer.Time(()=> myObject.TestMethod(123,1231,"another param")); 

依此類推。

0

不適用於泛型,但使用C++/CLI的可變參數模板(獲得對它們的支持時),您可以執行此操作。