2011-03-01 11 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

あなたはちょうどあなたが次のことを行うことができ、ボイドの戻り値の型を持っている代表団の後にある場合:

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

xmasツリーの場合+1ですが、この場合は 'HashSet <>'を試してください.. – nawfal

+1

技術的には、コードはArray.IndexOf(_actionTypes、d.GetType()、GetGenericTypeDefinition())!= -1でなければなりません。 –

関連する問題