2011-03-01 45 views
7

我試圖檢查給定類型是否爲動作委託,而不管參數數量多少。檢查某個類型是否爲動作委託

以下代碼是我知道如何做到這一點的唯一方法。

public static bool IsActionDelegate(this Type source) 
    { 
     return source == typeof(Action) || 
       source.IsOfGenericType(typeof(Action<>)) || 
       source.IsOfGenericType(typeof(Action<,>)) || 
       .... 
       source.IsOfGenericType(typeof(Action<,,,,,,,,,,,,,,,>)); 
    } 

IsOfGenericType()是我的另一個擴展方法,它做什麼它說,它會檢查該類型是否是給定的泛型類型。

有什麼更好的建議嗎?

回答

5

如果你只是有一個void返回類型,你可以做以下的代表後:

public static bool IsActionDelegate(Type sourceType) 
{ 
    if(sourceType.IsSubclassOf(typeof(MulticastDelegate)) && 
     sourceType.GetMethod("Invoke").ReturnType == typeof(void)) 
     return true; 
    return false; 
} 

這不會(爲此事或其他無效委託)ActionMethodInvoker區分雖然。正如其他答案建議你可以檢查類型名稱,但那有點味道;-) 如果你能澄清你想識別Action代表什麼原因,看看哪種方法最好。

+1

我不知道如果名稱搜索是非常糟糕的,因爲名稱來自庫命名空間而不是用戶代碼。 –

+0

偉大的洞察力,謝謝!我試圖做一個通用的Delegate.CreateDelegate方法。例如。 'CreateDelegate >(所有者,方法);'這是一項正在進行的工作,所以我不知道它是否可能。但這就是爲什麼我需要分析通用參數並檢查預期的代理類型。 –

+1

@Ritch - 它讓我想起使用javascript來檢查瀏覽器類型,而不是功能檢查 - 後者更乾淨。在這種情況下可能是沒有根據的,但如果我不是絕對必須的話,我不會碰這個名字。 – BrokenGlass

2

這似乎工作:

private static bool IsActionDelegate(this Type source) 
    { 
     var type = source.Name; 
     return source.Name.StartsWith("System.Action"); 
    } 

例子:

public static class Test 
{ 
    public static bool IsActionDelegate(this Type source) 
    { 
     var type = source.Name; 
     return source.Name.StartsWith("Action"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Action<string> one = s => { return; }; 
     Action<int, string> two = (i, s) => { return; }; 
     Func<int, string> function = (i) => { return null; }; 

     var single = one.GetType().IsActionDelegate(); 
     var dueces = two.GetType().IsActionDelegate(); 
     var func = function.GetType().IsActionDelegate(); 
    } 
} 

單和dueces是真實的。 func is false

+0

我想過檢查名稱,但希望有一個更清潔/更安全的解決方案。 –

+0

是的,這似乎很明顯。我只是好奇它,這就是我寫它的原因。我認爲當你將獨立的類型分解爲同等類型時,沒有什麼安全的。 –

2

這些是不同的類型,沒有什麼共同之處,只是它們的名字。唯一的半合理的快捷方式我能想到的:

public static bool IsActionDelegate(this Type source) 
{ 
    return source.FullName.StartsWith("System.Action"); 
} 

當然不是萬無一失,但任何人宣稱自己的類型System命名空間值得一些痛苦和折磨。

4
static Type[] _actionTypes = new[]{ 
     typeof(Action), 
     typeof(Action<>), 
     typeof(Action<,>), 
     typeof(Action<,,>), 
     typeof(Action<,,,>), 
     typeof(Action<,,,,>), 
     typeof(Action<,,,,,>), 
     typeof(Action<,,,,,,>), 
     typeof(Action<,,,,,,,>), 
     typeof(Action<,,,,,,,,>), 
     typeof(Action<,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,,,,,>), 
     typeof(Action<,,,,,,,,,,,,,,,>) 
    }; 
    private static bool IsAction(Delegate d) 
    { 
     return d != null && Array.IndexOf(_actionTypes, d.GetType()) != -1; 
    } 
+2

+1聖誕樹:)但在這種情況下,嘗試'HashSet <>'.. – nawfal

+1

從技術上講,代碼應該是Array.IndexOf(_actionTypes,d.GetType()。GetGenericTypeDefinition())!= - 1。 –

相關問題