중복 허용 속성을 만드는 방법


96

특성 클래스에서 상속 된 사용자 지정 특성을 사용하고 있습니다. 다음과 같이 사용하고 있습니다.

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

}

그러나 "Duplicate 'MyCustomAttribute'attribute"오류가 표시됩니다.
중복 허용 속성을 생성하려면 어떻게해야합니까?

답변:


184

막대기 AttributeUsage당신의 속성 (입의 네) 클래스와 세트에 속성 AllowMultipletrue:

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

6
그냥 궁금해-왜 "봉인 된"수업인가?
Tomas Aschan

18
Microsoft는 가능한 경우 속성 클래스를 봉인하는 것이 좋습니다. msdn.microsoft.com/en-us/library/2ab31zeh.aspx
Anton Gogolev

3
봉인 된 이유는 무엇입니까? 요컨대 : 속성 조회가 더 빨라지고 다른 영향은 없습니다.
Noel Widmer

다른 사람이 귀하의 코드를 재사용하는 것을 막는 것을 제외하고는. DataAnnotations의 유효성 검사 속성은 봉인 되어 있지 않으므로 특수화를 만들 수 있으므로 매우 유용합니다.
Neutrino

@Neutrino seal은 클래스가 상속 될 것으로 예상하지 않거나 디자인하지 않을 때마다 사용해야합니다. 또한 상속이 버그의 원인이 될 수있는 경우 예 : 스레드로부터 안전한 구현.
Francisco Neto

20

AttributeUsageAttribute ;-p

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

그러나 ComponentModel ( TypeDescriptor)을 사용하는 경우 멤버 당 하나의 속성 인스턴스 (속성 유형 당) 만 지원합니다. 원시 반사는 모든 숫자를 지원합니다 ...


13

Anton의 솔루션 은 맞지만 또 다른 문제가 있습니다.

간단히 말해, 사용자 지정 속성이 TypeId를 재정의하지 않는 한이를 통해 액세스하면 PropertyDescriptor.GetCustomAttributes()속성의 단일 인스턴스 만 반환됩니다.


그러나 다음을 통해 작동합니다. var customAtt = propertyInfo.GetCustomAttributes <MyCustomAttribute> ();
oo_dev

8

기본적으로 Attributes는 단일 필드 / 속성 등에 한 번만 적용되도록 제한됩니다. MSDN Attribute클래스 정의 에서 이것을 볼 수 있습니다 .

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

따라서 다른 사람들이 언급했듯이 모든 하위 클래스는 동일한 방식으로 제한되며 동일한 속성의 여러 인스턴스가 필요한 경우 명시 적으로 다음으로 설정 AllowMultiple해야합니다 true.

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

여러 사용을 허용 하는 TypeId속성 에서는 속성PropertyDescriptor.Attributes 예상 대로 작동 하도록 속성재정의해야합니다 . 이를 수행하는 가장 쉬운 방법은 속성 인스턴스 자체를 반환하는 속성을 구현하는 것입니다.

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

(이 답변을 게시하는 것은 다른 사람이 틀 렸기 때문이 아니라보다 포괄적이고 표준적인 답변이기 때문입니다.)


3

대안으로 시퀀스를 허용하도록 속성을 재 설계하는 것을 고려하십시오.

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

또는

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

그런 다음 값을 구문 분석하여 속성을 구성하십시오.

이에 대한 예는 www.codeplex.com/aspnet 에서 ASP.NET MVC 소스 코드의 AuthorizeAttribute를 확인하십시오 .


3
MyCustomAttribute생성자 가 수정자를 사용하거나 사용하지 않고 문자열 배열 a를 받도록하는 것도 가능합니다 . 그런 다음 구문 (with ) 으로 적용 할 수 있습니다 . string[]params[MyCustom("CONTROL", "ALT", "SHIFT", "D")]params
Jeppe Stig Nielsen

2

AttributeUsage를 추가 한 후이 속성을 Attribute 클래스에 추가해야합니다.

public override object TypeId
{
  get
  {
    return this;
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.