Cách tạo các thuộc tính được phép trùng lặp


96

Tôi đang sử dụng 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:

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

}

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

Câu trả lời:


184

Dán một AttributeUsagethuộc tính vào lớp Thuộc tính của bạn (vâng, thật tuyệt) và đặt AllowMultiplethành true:

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

6
Chỉ tò mò - tại sao một lớp học "niêm phong"?
Tomas Aschan

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

3
Tại sao lại niêm phong? Tóm lại: Làm cho việc tra cứu thuộc tính nhanh hơn và không có tác động nào khác.
Noel Widmer

Ngoại trừ việc nó ngăn không cho bất kỳ ai khác sử dụng lại mã của bạn. Cần lưu ý rằng các thuộc tính xác thực trong DataAnnotations không được niêm phong, điều này cực kỳ hữu ích vì nó có thể tạo ra các chuyên ngành của chúng.
Neutrino

@Neutrino niêm phong nên được sử dụng bất cứ khi nào bạn không mong đợi hoặc không thiết kế các lớp của mình để kế thừa. Thêm vào đó, khi kế thừa có thể trở thành nguồn gốc của lỗi, ví dụ: Triển khai an toàn theo luồng.
Francisco Neto

20

AttributeUsageAttribute ;-p

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

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


13

Giải pháp của Anton là đúng, nhưng có một vấn đề khác .

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


Nhưng nó hoạt động thông qua: var customAtt = propertyInfo.GetCustomAttributes <MyCustomAttribute> ();
oo_dev

8

Theo mặc định, Attributes được giới hạn chỉ được áp dụng một lần cho một trường / thuộc tính / v.v. Bạn có thể thấy điều này từ định nghĩa của Attributelớp trên MSDN :

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

Do đó, 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 rõ ràng thiết AllowMultipleđể true:

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

Trên các thuộc tính cho phép nhiều cách sử dụng, bạn cũng nên ghi đè thuộc TypeIdtính đó để đảm bảo rằng các thuộc tính đó PropertyDescriptor.Attributes hoạt động như mong đợi. Cách dễ nhất để làm điều này là triển khai thuộc tính đó để trả về bản thân thuộc tính:

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

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


3

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

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

hoặc là

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

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

Để có ví dụ về điều này, hãy xem AuthorizeAttribute trong mã nguồn ASP.NET MVC tại www.codeplex.com/aspnet .


3
Thậm chí có thể có hàm MyCustomAttributetạo nhận một mảng chuỗi, a string[], có hoặc không có paramsbổ ngữ. Sau đó, nó có thể được áp dụng với cú pháp [MyCustom("CONTROL", "ALT", "SHIFT", "D")](with params).
Jeppe Stig Nielsen

2

Sau khi bạn thêm Thuộc tính, hãy đảm bảo rằng bạn thêm thuộc tính này vào lớp Thuộc tính của mình

public override object TypeId
{
  get
  {
    return this;
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.