배열 또는 기타 가변 개수의 인수를 사용하여 C # 특성을 초기화 할 수 있습니까?


105

가변 개수의 인수로 초기화 할 수있는 속성을 생성 할 수 있습니까?

예를 들면 :

[MyCustomAttribute(new int[3,4,5])]  // this doesn't work
public MyClass ...

12
배열에 대한 구문이 잘못되었습니다. "new int [] {3,4,5}"여야합니다.
David Wengier

답변:


178

속성은 배열을 사용합니다. 속성을 제어하는 ​​경우 params대신 사용할 수도 있습니다 (소비자에게 더 좋은 IMO).

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

배열 생성 구문이 해제됩니다.

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(int[] values) {
        this.Values = values;
    }
}

[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }

33

할 수 있지만 CLS 규격이 아닙니다.

[assembly: CLSCompliant(true)]

class Foo : Attribute
{
    public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}

쇼 :

Warning 1   Arrays as attribute arguments is not CLS-compliant

일반적인 반사 사용의 경우 여러 속성을 갖는 것이 바람직 할 수 있습니다.

[Foo("abc"), Foo("def")]

그러나 이것은 모든 속성의 단일 인스턴스 만 지원되는 TypeDescriptor/ PropertyDescriptor에서는 작동하지 않습니다 (첫 번째 또는 마지막 승리 중 어느 것이 든 기억할 수 없습니다).


3
참고 : 여러 속성에는 속성에 AttributeUsage 속성이 필요합니다. stackoverflow.com/questions/553540/...
russau

23

다음과 같이 생성자를 선언하십시오.

public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(params int[] t)
    {
    }
}

그런 다음 다음과 같이 사용할 수 있습니다.

[MyCustomAttribute(3, 4, 5)]


12

괜찮습니다. 사양, 섹션 17.2에서 :

다음 명령문이 모두 참인 경우 표현식 E는 attribute-argument-expression 입니다.

  • E 유형은 특성 매개 변수 유형 (§17.1.3)입니다.
  • 컴파일 타임에 E의 값은 다음 중 하나로 확인할 수 있습니다.
    • 상수 값.
    • System.Type 개체입니다.
    • attribute-argument-expressions 의 1 차원 배열입니다 .

예를 들면 다음과 같습니다.

using System;

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class SampleAttribute : Attribute
{
    public SampleAttribute(int[] foo)
    {
    }
}

[Sample(new int[]{1, 3, 5})]
class Test
{
}

5
하지만 CLS 규정 준수에주의하십시오
Marc Gravell

4

예,하지만 전달하려는 배열을 초기화해야합니다. 다음은 다양한 수의 명령 줄 옵션을 테스트하는 단위 테스트의 행 테스트 예제입니다.

[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }

2

할 수 있습니다. 또 다른 예는 다음과 같습니다.

class MyAttribute: Attribute
{
    public MyAttribute(params object[] args)
    {
    }
}

[MyAttribute("hello", 2, 3.14f)]
class Program
{
    static void Main(string[] args)
    {
    }
}

1

Marc Gravell의 답변을 따르기 위해 배열 매개 변수로 속성을 정의 할 수 있지만 배열 매개 변수로 속성을 적용하는 것은 CLS 규격이 아닙니다. 그러나 배열 속성을 사용하여 특성을 정의하는 것만으로도 완벽하게 CLS를 준수합니다.

이것을 깨달은 것은 CLS 호환 라이브러리 인 Json.NET에 개체 배열 인 ItemConverterParameters라는 속성이있는 속성 클래스 JsonPropertyAttribute가 있다는 것입니다.

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