2009-08-05 3 views
54

에 물체를 통과하는 방법은 다음과 같이 속성 생성자로 객체를 전달하려고 오전 :이 속성 생성자와속성 생성자

[PropertyValidation(new NullOrEmptyValidatorScheme())] 
public string Name { get; private set; } 

:

public PropertyValidationAttribute(IValidatorScheme validator) { 
     this._ValidatorScheme = validator; 
    } 

코드는 컴파일되지 않습니다. 위와 같이 객체에 속성을 어떻게 전달할 수 있습니까?

편집 : 예 NullOrEmptyValidatorScheme은 IValidatorScheme을 구현합니다.

오류 : 오류 CS0182 : 특성 인수는 상수 식, typeof 식 또는 특성 매개 변수 형식의 배열 작성 식이어야합니다.

+0

에게 컴파일 오류가 무엇입니까? 'NullOrEmptyValidatorScheme'이'IValidatorScheme'을 구현하고 있다는 것을 확신합니까? –

+0

속성 구문과 관련하여 이것은 유효한 코드이므로 객체에 관한 것이어야합니다. –

+2

@ kek444 - 아니요 ... 내 대답에 spec 섹션을 추가하고 있습니다 ... –

답변

65

속성에 대한 값은 단순 유형으로 제한됩니다. 예를 들어 기본 상수 (문자열 포함) 및 typeof ... new 또는 다른 복잡한 코드를 사용할 수 없습니다. 간단히 말해서; 너는 이것을 할 수 없다. 당신은 그것을 비록 유형 제공 할 수 있습니다 :

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)] 

즉이 PropertyValidation의 ctor는 Type 소요를하고, 객체를 생성하는 코드 내부에 Activator.CreateInstance를 사용합니다. 이상적으로 문자열을 내부적으로 저장해야합니다 (AssemblyQualifiedName). ECMA의 334v4에서

: 이전 포스터는 그 값에 직접 직렬화 할 필요가 있기 때문에, 종류가 매우 심각 당연하게도 (제한 속성 인수에 사용 언급 한 바와 같이

§24.1.3 Attribute parameter types

The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:

  • One of the following types: bool , byte , char , double , float , int , long , short , string .
  • The type object .
  • The type System.Type .
  • An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility.
  • Single-dimensional arrays of the above types.

§24.2 Attribute specification

...

An expression E is an attribute-argument-expression if all of the following statements are true:

  • The type of E is an attribute parameter type (§24.1.3).
  • At compile-time, the value of E can be resolved to one of the following:
    • A constant value.
    • A typeof-expression (§14.5.11) specifying a non-generic type, a closed constructed type (§25.5.2), or an unbound generic type (§25.5).
    • A one-dimensional array of attribute-argument-expressions.
+0

허용되는 값 중 열거 형으로 허용되는 값 중 두 번째 참조입니다. 그러나 구현은 간단하지 않습니다. enum을 사용하여 구현 예제를 알고 있습니까? – QueueHammer

+0

@QueueHammer'[DefaultValue (AnyEnum.SomeValue)]'이면 충분합니다. 그렇지 않으면'[System.Xml.Serialization.XmlElement (Form = System.Xml.Schema.XmlSchemaForm.Qualified)] ' –

10

어셈블리 메타 데이터 BLOB). 그 사용될 수있다, 당신은 아마, typeofs을 활용하는 솔루션을 만들 수 있다고 말했다

. 예를 들어

:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme))] 
public string Name { get; private set; } 

이 구문은 완벽하게 합법적이다. 유효성 검사기 유형을 가져와야하는 특성을 읽는 코드는 유효성 검사기의 새 인스턴스를 만듭니다 (적절한 경우 발의기 유형에 키가있는 유효성 검사기의 캐시를 유지할 수도 있습니다 - 이것은 매우 일반적인 기술입니다). 그런 다음 호출합니다 . 또한

+0

와 같은 답변을 주셔서 감사합니다. 나는 Marc에게 대답을 받아 들였다. 그러나 캐시 사용에 대한 귀하의 제안은 도움이되며, 많은 Activator.CreateInstance 호출을 저장하기 위해이 작업을 계획했습니다. – theringostarrs

5

... 당신은 기본 값을 "널 (null)"를 넣어 간단하지만 디폴트 값을 기본값으로 할 수 있습니다 확인 ('거짓', '7', '

(나는 그것이 마이크로 소프트 버그라고 생각) "테스트").

다음 예제는 당신에게 다음과 같은 오류를 줄 것이다 : 를 속성 인수는 속성 매개 변수 형식의 발현 또는 배열 생성 식 대해서 typeof, 상수 식이어야 파일
: ... \ CSC

public class SampleAttribute : Attribute 
{ 
    private string _test; 
    public SampleAttribute(string test = null) 
    { 
     _test = test; 
    } 
} 

[Sample] 
public class Toto 
{ 

} 
+0

관련이있을 수 있습니다 : "속성 및 명명 된/선택적인 생성자 매개 변수가 작동하지 않음"http://stackoverflow.com/q/8189807/276648 – user276648

+0

user276648에게 나는 당신이 맞다고 생각합니다. . 감사 ! –

+0

실제로 샘플로는 컴파일러 버그 (Mono로 컴파일 할 때 작성한 것을 의미)와 관련이있을 수 있습니다. http://stackoverflow.com/q/8290853 – user276648