2010-08-13 37 views
13

Xin lỗi nếu đây là câu hỏi noob ngu ngốc, hãy nhẹ nhàng với tôi Tôi đang cố gắng tìm hiểu ...C# Phương pháp mở rộng để kiểm tra các thuộc tính

Tôi muốn thử nghiệm các phương pháp thuộc tính như mô hình và bộ điều khiển. Chủ yếu là để đảm bảo rằng họ có đúng attrbute tức là Bắt buộc. Nhưng tôi cũng sử dụng điều này như một thử nghiệm với các phương pháp mở rộng và Lambdas.

Những gì tôi muốn là một phương pháp mà khi implimented trông một số điều như

Controller controller = new Controller(); 
controller.MethodName(params).HasAttribute<AttributeName>(); 

phương pháp khuyến nông Iveused một chút nhưng không đến mức độ này .. Tôi chắc chắn điều này là đủ đơn giản để làm nhưng cant dường như để có được generics của tôi vv chính xác.

+0

Tôi không chắc chắn tôi Dưới stand, 'HasAttribute' là một phương thức mở rộng có thể cho bạn biết nếu phương thức' MethodName' của lớp 'Controller' có thuộc tính' AttributeName' không? – Benjol

+0

Yeah thats khá nhiều những gì tôi sau. Đối với mục đích thử nghiệm đơn vị nhưng cũng chỉ cho tôi như là một tập thể dục học tập –

Trả lời

19

có lẽ bạn đang tìm kiếm này:

01.
Controller controller = new Controller(); 
bool ok = controller.GetMethod(c => c.MethodName(null, null)) 
    .HasAttribute<AttributeName>(); 

Điều tuyệt vời khi viết nó như thế này là bạn đã hoàn toàn biên dịch hỗ trợ thời gian. Tất cả các giải pháp khác cho đến nay sử dụng chuỗi ký tự để xác định các phương thức.

Dưới đây là việc triển khai các phương pháp GetMethodHasAttribute<T> mở rộng:

public static MethodInfo GetMethod<T>(this T instance, 
    Expression<Func<T, object>> methodSelector) 
{ 
    // Note: this is a bit simplistic implementation. It will 
    // not work for all expressions. 
    return ((MethodCallExpression)methodSelector.Body).Method; 
} 

public static MethodInfo GetMethod<T>(this T instance, 
    Expression<Action<T>> methodSelector) 
{ 
    return ((MethodCallExpression)methodSelector.Body).Method; 
} 

public static bool HasAttribute<TAttribute>(
    this MemberInfo member) 
    where TAttribute : Attribute 
{ 
    return GetAttributes<TAttribute>(member).Length > 0; 
} 

public static TAttribute[] GetAttributes<TAttribute>(
    this MemberInfo member) 
    where TAttribute : Attribute 
{ 
    var attributes = 
     member.GetCustomAttributes(typeof(TAttribute), true); 

    return (TAttribute[])attributes; 
} 
+1

+1 Nếu mã này đang được sản xuất, tôi chắc chắn muốn kiểm tra thời gian biên dịch. –

+0

Làm việc một điều trị Cảm ơn Steven. ps @ Jerod lý do tại sao thời gian biên dịch kiểm tra sản xuất. Chỉ tò mò thôi. Không có mã nào không được sản xuất. Bạn có nghĩa là không có dây ma thuật như một số phương pháp khác? –

+0

tuyệt vời! Tôi thích nó! :-D – theburningmonk

-1

Bạn đang tìm kiếm lớp Reflection - nó cho phép bạn kiểm tra đối tượng được truyền. Tuy nhiên, thành thực mà nói, nếu bạn muốn có một trường được gọi là Bắt buộc trong một mô hình, hoặc một phương pháp được gọi là IsRequired trong một bộ điều khiển hơn là thực hiện trong một giao diện và yêu cầu giao diện đó thực hiện.

Cụ thể cho các thuộc tính thấy here:

Type t = something; 
System.Console.WriteLine("Author information for {0}", t); 
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t); // reflection 

foreach (System.Attribute attr in attrs) 
{ 
    if (attr is Author) 
    { 
     Author a = (Author)attr; 
      System.Console.WriteLine(" {0}, version {1:f}", a.GetName(), a.version); 
    } 
} 
+0

Chúc mừng cho các liên kết Tôi đang nhìn vào sự phản ánh bây giờ. Tôi thấy bạn đang chỉ ra rằng đó là một bài tập học tập nhưng tôi không muốn làm lộn xộn giải pháp của mình với Giao diện không cần thiết. Đây là bài tập thử nghiệm đơn vị nhiều hơn. Tôi biết nó có lẽ không phải là tốt nhất của phương pháp tiếp cận nhưng tôi có vẻ như ý tưởng kiểm tra cho những thứ như ủy quyền vv –

0

Bạn có thể kiểm tra xem một phương pháp có một thuộc tính cụ thể bằng cách làm điều này:

typeof(Controller).GetMethod("MethodName").GetAttributes<AttributeName>().Any(); 

Xét về phương pháp mở rộng chính nó, với điều kiện là bạn' đang tìm kiếm một phương pháp tiện ích mở rộng trên loại Bộ điều khiển, cách thực hiện như sau:

public static bool HasAttribute<A>(this Controller controller, string methodName) 
{ 
    return controller.GetType().GetMethod(methodName).GetCustomAttributes(typeof(A), true).Any(); 
} 

Hãy nhớ rằng, phương pháp khuyến nông được gọi vào một thể hiện, vì vậy để sử dụng này, bạn vẫn cần một thể hiện của điều khiển:

var controller = new Controller(); 
Assert.IsTrue(controller.HasAttribute<AttributeName>("Method1")); 
+0

Tôi thích phương pháp đó và Ryan. Hãy suy nghĩ tôi có thể cobble một cái gì đó với nhau từ những/ –

1

Tôi không nghĩ rằng bạn sẽ có thể thực hiện điều đó chính xác như bạn mô tả. Phần MethodName(params) của câu lệnh của bạn sẽ thực sự thực thi phương thức, trả về bất kỳ phương thức nào trả về và không phải thông tin về phương thức.

Điều bạn muốn làm là chuyển một số MethodInfo vào lớp mở rộng của bạn, sử dụng phản chiếu. Vì vậy, thay vì ví dụ của bạn, có thể bạn muốn kết thúc với một cái gì đó như:

controller.GetType().GetMethod(methodName).HasAttribute<AttributeName>(); 

Bạn có thể có thể đơn giản hóa này xuống đến một phương pháp mở rộng duy nhất trên lớp điều khiển bằng cách đóng gói GetType().GetMethod(), như vậy:

controller.MethodHasAttribute(methodName, attributeName); 
+0

Chúc mừng Ryan Tôi thích cách tiếp cận đó và cảm ơn cho giải thích về việc thực hiện D'oh chưa bao giờ nghĩ về điều đó chút. –

1

có thể không hoàn toàn làm chính xác điều đó với phương pháp khuyến nông, nhưng điều này gần:

public static class Program 
{ 
    static void Main(string[] args) 
    { 
    Controller c1 = new Controller(); 
    Action a1 = c1.Method1; 
    Console.WriteLine(a1.HasAttribute<Controller.TestAttribute>()); 
    } 

    public static bool HasAttribute<T>(this Action method) 
    { 
    return method.Method.GetCustomAttributes(typeof(T), false).Any(); 
    } 
} 

class Controller 
{ 
    [AttributeUsage(AttributeTargets.Method)] 
    public class TestAttribute : System.Attribute 
    { 
    } 

    [Test()] 
    public void Method1() 
    { 
    } 
} 
1

Cách sử dụng:

bool hasAttribute = controller.HasMethodAttribute<TestAttribute>("Test") 

Extension:

public static bool HasMethodAttribute<TAttribute>(this object obj, string methodName) 
{ 
    Type type = obj.GetType(); 

    MethodInfo method = type.GetMethod(methodName); 
    if(method == null) 
    { 
     throw new ArgumentException(string.Format( 
      "Method '{0}' not found on object '{1}'", methodName, type.Name)); 
    } 

    return method.GetCustomAttributes(typeof(TAttribute), true).Length > 0 ; 
} 
+0

Tại sao lại là downvote? Vui lòng giải thích! –

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