2009-02-16 58 views
69

Tôi đang sử dụng một thuộc tính tùy chỉnh được kế thừa từ một lớp thuộc tính. Tôi đang sử dụng nó như thế này:Cách tạo thuộc tính được phép trùng lặp

[MyCustomAttribute("CONTROL")] 
    [MyCustomAttribute("ALT")] 
    [MyCustomAttribute("SHIFT")] 
    [MyCustomAttribute("D")] 
    public void setColor() 
{ 

} 

Nhưng lỗi "Thuộc tính 'MyCustomAttribute' thuộc tính" được hiển thị.
Làm cách nào để tạo thuộc tính được phép trùng lặp?

Trả lời

132

Stick một thuộc tính AttributeUsage vào lớp Thuộc tính của bạn (vâng, đó là miếng) và thiết lập AllowMultiple để true:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public sealed class MyCustomAttribute: Attribute 
+5

Chỉ tò mò - tại sao một lớp "kín"? –

+15

Microsoft khuyến cáo niêm phong các lớp thuộc tính bất cứ khi nào có thể: http://msdn.microsoft.com/en-us/library/2ab31zeh.aspx –

+1

Tại sao bị niêm phong? Tóm lại: Giúp tra cứu thuộc tính nhanh hơn và không có tác động nào khác. –

16

AttributeUsageAttribute ;-p

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public class MyAttribute : Attribute 
{} 

Lưu ý, tuy nhiên, nếu bạn là sử dụng ComponentModel (TypeDescriptor), nó chỉ hỗ trợ một cá thể thuộc tính (cho mỗi loại thuộc tính) cho mỗi thành viên; phản xạ thô hỗ trợ bất kỳ số nào ...

3

Thay vào đó, hãy suy nghĩ về việc thiết kế lại thuộc tính của bạn để cho phép chuỗi.

[MyCustomAttribute(Sequence="CONTROL,ALT,SHIFT,D")] 

hoặc

[MyCustomAttribute("CONTROL-ALT-SHIFT-D")] 

sau đó phân tích các giá trị cấu hình thuộc tính của bạn.

Ví dụ về việc này, hãy kiểm tra mã nguồn AuthorizeAttribute trong ASP.NET MVC tại www.codeplex.com/aspnet.

+1

Thậm chí có thể có hàm tạo 'MyCustomAttribute' lấy một mảng * của chuỗi, một chuỗi' string [] ', có hoặc không có công cụ sửa đổi' params'. Sau đó, nó có thể được áp dụng với cú pháp '[MyCustom (" CONTROL "," ALT "," SHIFT "," D ")]' (với 'params'). –

11

Anton's solution là chính xác, nhưng có another gotcha.

Tóm lại, trừ khi tùy chọn ghi đè tùy chỉnh của bạn TypeId, sau đó truy cập nó thông qua PropertyDescriptor.GetCustomAttributes() sẽ chỉ trả về một phiên bản duy nhất thuộc tính của bạn.

1

Sau khi bạn thêm AttributeUsage, hãy chắc chắn bạn thêm khách sạn này đến lớp Thuộc tính của bạn

public override object TypeId 
{ 
    get 
    { 
    return this; 
    } 
} 
2

Theo mặc định, Attribute s được giới hạn được áp dụng một lần duy nhất vào một trường duy nhất/tài sản/etc. Bạn có thể thấy điều này từ definition of the Attribute class on MSDN:

[AttributeUsageAttribute(..., AllowMultiple = false)] 
public abstract class Attribute : _Attribute 

Vì vậy, như những người khác đã lưu ý, tất cả các lớp con được giới hạn trong cùng một cách, và bạn nên yêu cầu nhiều trường hợp của các thuộc tính giống nhau, bạn cần phải thiết lập một cách rõ ràng AllowMultiple để true :

[AttributeUsage(..., AllowMultiple = true)] 
public class MyCustomAttribute : Attribute 

Mở thuộc tính cho phép nhiều tập quán, you should also override the TypeId property để đảm bảo rằng các đặc tính như PropertyDescriptor.Attributes công việc như mong đợi. Cách đơn giản nhất để làm điều này là để thực hiện điều đó tài sản để trả lại ví dụ thuộc tính riêng của mình:

[AttributeUsage(..., AllowMultiple = true)] 
public class MyCustomAttribute : Attribute 
{ 
    public override object TypeId 
    { 
     get 
     { 
      return this; 
     } 
    } 
} 

(gửi bài trả lời này không phải vì những người khác là sai, nhưng vì đây là một câu trả lời toàn diện hơn/kinh điển.)

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