2011-03-01 35 views
7

Tôi đang cố gắng kiểm tra xem một loại nhất định có phải là đại diện hành động hay không, bất kể số lượng thông số.Kiểm tra xem một loại nhất định có phải là đại diện Hành động

Mã sau đây là cách duy nhất tôi biết cách thực hiện việc này.

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

IsOfGenericType() là một phương pháp mở rộng khác của tôi, theo những gì nó nói, nó sẽ kiểm tra xem loại có thuộc loại chung nhất định hay không.

Bất kỳ đề xuất nào tốt hơn?

Trả lời

5

Nếu bạn là ngay sau khi các đại biểu rằng có một kiểu void trở lại bạn có thể làm như sau:

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

này sẽ không phân biệt được giữa ActionMethodInvoker (hoặc đại biểu khoảng trống khác cho rằng vấn đề) mặc dù. Khi các câu trả lời khác gợi ý bạn có thể kiểm tra tên loại, nhưng loại đó có mùi ;-) Sẽ giúp ích nếu bạn có thể làm rõ lý do bạn muốn xác định các đại biểu là Action để xem phương pháp nào sẽ hoạt động tốt nhất.

+1

Tôi không biết nếu tìm kiếm theo tên là tất cả những gì xấu cho rằng tên đến từ một không gian tên thư viện và không phải mã người dùng. –

+0

Thông tin chi tiết tuyệt vời, cảm ơn! Tôi đang cố gắng thực hiện một phương thức Delegate.CreateDelegate chung. Ví dụ. 'CreateDelegate > (chủ sở hữu, phương pháp);' Đó là một công việc đang diễn ra nên tôi chưa biết liệu nó có khả thi hay không. Nhưng đó là lý do tại sao tôi cần phân tích tham số chung và kiểm tra loại đại biểu nào được mong đợi. –

+1

@Ritch - nó nhắc tôi kiểm tra loại trình duyệt trong javascript thay vì tính năng kiểm tra - sau này là sạch hơn nhiều. Có lẽ không có cơ sở trong trường hợp này, nhưng tôi sẽ không chạm vào tên nếu tôi không hoàn toàn phải làm vậy. – BrokenGlass

2

Điều này dường như làm việc:

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

Ví dụ:

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

Độc thân và dueces là đúng sự thật. func là false

+0

Tôi đã nghĩ đến việc kiểm tra tên trước đây, nhưng hy vọng có giải pháp sạch hơn/an toàn hơn. –

+0

Vâng, nó có vẻ hiển nhiên. Tôi chỉ tò mò về nó, đó là lý do tại sao tôi viết nó. Tôi không nghĩ rằng có bất cứ điều gì an toàn khi bạn đang mucking với các loại độc lập và đối xử với chúng như là tương đương. –

2

Đây là những loại riêng biệt không có điểm chung nhưng là tên của chúng. Các chỉ shortcut bán hợp lý tôi có thể nghĩ:

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

Chắc chắn không phải không an toàn, nhưng bất cứ ai tuyên bố loại riêng của mình trong namespace System xứng đáng một số đau đớn và đau khổ.

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 cho cây xmas :) Nhưng trong trường hợp này hãy thử một 'HashSet <>' .. – nawfal

+1

Về mặt kỹ thuật mã nên là Array.IndexOf (_actionTypes, d.GetType(). GetGenericTypeDefinition())! = - 1. –

Các vấn đề liên quan