2009-08-05 22 views
54

içine nesneleri geçmek nasıl aşağıdaki gibi bir Nitelikler yapıcı içine nesneleri geçmek çalışılıyor: Bu özellik yapıcısı ilebir özellik yapıcı

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

:

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

kod derlemek olmaz. Bir nesneyi yukarıdaki gibi bir öznitelikte nasıl geçirebilirim?

DÜZENLEME: Evet NullOrEmptyValidatorScheme, IValidatorScheme'yi uygular.

Hata: error CS0182: Bir öznitelik argümanı, bir öznitelik parametresi türünün bir ifadesi, bir tür ifadesi veya dizi oluşturma ifadesi olmalıdır.

+0

Derleme hatası nedir? 'NullOrEmptyValidatorScheme' 'IValidatorScheme' uygular mı? –

+0

Öznitelik sözdizimi söz konusu olduğunda, bu geçerli bir koddur, bu nedenle nesneleriniz hakkında bir şey olması gerekir. –

+2

@ kek444 - hayır değil ... Cevap kısmına spec bölümünü ekliyorum ... –

cevap

65

Öznitelik değerleri basit türlerle sınırlıdır; Örneğin, temel sabitler (dizeler dahil) ve typeof ... new veya diğer daha karmaşık kodları kullanamazsınız. Kısacası; bunu yapamazsın Gün içinde bir çok olsa tip verebilir:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)] 

yani PropertyValidation ctor bir Type alır ve nesne oluşturmak için kod içindeki Activator.CreateInstance kullanın. İdeal olarak dize dahili olarak saklamanız gerektiğini unutmayın (AssemblyQualifiedName). ECMA 334v4 itibaren

: Önceki posterleri değerleri doğrudan Serileştirilecek gerektiğinden, türleri, oldukça ciddi anlaşılır (kısıtlanır nitelik argümanları kullanmak belirtildiği gibi

§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.

ve

§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

Bu, izin verilen değerlerden birinin enum olduğu ikinci referanstır, ancak bu uygulama önemsiz değildir. Enum kullanarak örnek uygulamalar biliyor musunuz? – QueueHammer

+0

@QueueHammer '[DefaultValue (AnyEnum.SomeValue)]' yeterli olmalıdır; aksi halde, bir şey gibi [System.Xml.Serialization.XmlElement (Form = System.Xml.Schema.XmlSchemaForm.Qualified)] ' –

10

derleme meta veri bloğu). Bu kullanılabilir olarak, muhtemelen, typeofs kullanan bir çözüm oluşturabilir söyledi

. Örneğin

:

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

Bu sözdizimi tamamen yasal. Özniteliklerinizin değerini doğrulayıcı olarak okuyan kod, validator'un yeni bir örneğini yaratır (uygunsa, validator türlerine göre doğrulanmış bir geçerlilik denetleyicisi önbelleği bile tutabilir - bu oldukça yaygın bir tekniktir) ve sonra onu çağırır. . Ayrıca

+0

Yanıtladığınız için teşekkürler. Marc'a kabul edilen cevabı verdim. Ancak önbellek kullanma önerileriniz faydalıdır ve birçok Activator.CreateInstance çağrısından tasarruf etmek için bunu yapmayı düşünmüştü. – theringostarrs

5

... Varsayılan bir değerini "boş" koymak ama basit varsayılan değeri varsayılan olamaz vardır Tamam ('yanlış', '7', '

(Ben bir Microsoft Hata olduğunu düşünüyorum) "Ölçek").

Sonraki örnek aşağıdaki hata verir: Bir öznitelik argümanı bir öznitelik parametresi türü ifadesi veya dizi oluşturma ifadesi typeof, sabit bir ifadesi olmalıdır dosyasında
: ... \ CSC

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

[Sample] 
public class Toto 
{ 

} 
+0

Might ilişkili: "Nitelikler ve Adlandırılmış/İsteğe bağlı yapıcı parametreleri çalışmıyor" http://stackoverflow.com/q/8189807/276648 – user276648

+0

Kullanıcı276648'e göre, haklısınız, ilgili oldukları ve çözümün daha eksiksiz olduğu anlaşılıyor . Teşekkürler ! –

+0

Aslında, örneğinizle birlikte bir derleyici hatası ile ilgili olabilir (yazdığınız şey, Mono tarafından derlendiğinde işe yarayabilir) http://stackoverflow.com/q/8290853 – user276648