2011-03-01 19 views
7

Belirli bir türün, parametre miktarından bağımsız olarak bir eylem temsilcisi olup olmadığını kontrol etmeye çalışıyorum.Belirli bir türün Action degeni olup olmadığını kontrol etme

Aşağıdaki kod, bunu nasıl yapacağımı bildiğim tek yoldur.

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

IsOfGenericType()

benim başka uzantısı yöntemi olup buna tipi verilen jenerik türde olup olmadığını kontrol eder, diyor yok ki.

Daha iyi bir öneri?

cevap

5

size hemen aşağıdaki yapabileceği bir dönüş türü void delegeler sonra:

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

Bu (ya da bu konuda başka boşluk delege) Action ve MethodInvoker ayırt edemezdi ama. Diğer cevaplar tür adını incelemenizi önerdiğini, ancak bu tür kokuyor ;-) Hangi yaklaşımın en iyi işe yaradığını görmek için Action delegelerini belirlemek istediğinizi açıklığa kavuşturmak yardımcı olabilir.

+1

İsme göre arama yapılıyorsa, adın bir kullanıcı adı değil, bir kitaplık ad alanından gelmesi durumunda, o kadar da kötü. –

+0

Harika bir fikir, teşekkürler! Genel bir Delegate.CreateDelegate yöntemi yapmaya çalışıyorum. Örneğin. 'CreateDelegate > (sahibi, yöntemi);' Ben mümkün olup olmayacağını henüz bilmiyorum devam eden bir çalışmadır bu. Ama bu yüzden jenerik parametreyi analiz etmem ve ne tip bir temsilci beklendiğini kontrol etmem gerekiyor. –

+1

@Ritch - yerine özellik denetimi javascript tarayıcı türünü denetlemek hatırlatıyor - daha sonra daha temiz. Belki bu durumda haksızlık olur, ama kesinlikle zorunda olmadığım takdirde isme dokunmazdım. Noel ağacı – BrokenGlass

2

Bu iş gibi görünüyor:

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

Örnek:

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(); 
    } 
} 

Tek ve dueces doğrudur. func false

+0

Adı daha önce kontrol etmeyi düşündüm, ama daha temiz/daha güvenli bir çözüm olduğunu umuyorum. –

+0

Yea, açık görünüyordu. Bunu merak ettim, bu yüzden onu yazdım. Bağımsız türlerle uğraşırken ve onları eşdeğer olarak muamele ettiğinizde güvenli bir şey olduğunu düşünmüyorum. –

2

Bunlar, ortak hiçbir şeyi olmayan, ancak isimleri olan farklı türlerdir. Aklıma gelen tek yarı makul kısayol:

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

şüphesiz tam güvenli, ama herkese Sistem ad kendi türlerini beyan bazı ağrı ve acı hak değil.

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 :) Ama bu durumda bir 'HashSet <>' .. – nawfal

+1

Teknik kodu olmalıdır Array.indexOf deneyin (_actionTypes, d.GetType() GetGenericTypeDefinition().) = - 1. –

İlgili konular