2009-08-05 59 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'吗? – 2009-08-05 20:44:53

+0

作为属性语法而言,这是有效的代码,所以它必须是关于你的对象的东西。 – 2009-08-05 20:48:03

+2

@ kek444 - 不,它不是......我将规范部分添加到我的回复中...... – 2009-08-05 20:57:27

回答

65

属性的值仅限于简单类型;例如,基本常量(包括字符串)和typeof ...您不能使用new或其他更复杂的代码。简而言之;你不能这样做。你可以给它的类型虽然:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)] 

PropertyValidation构造函数需要一个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

这是允许值之一的第二个引用,它是一个枚举,但实现并不是微不足道的。你知道任何使用枚举的示例实现吗? – QueueHammer 2016-12-12 15:53:24

+0

@QueueHammer'[DefaultValue(AnyEnum.SomeValue)]'应该足够了;否则,就像'[System.Xml.Serialization.XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]' – 2016-12-12 16:02:45

10

正如前面的海报指出,该类型的属性参数使用都相当严格限制(可以理解的,因为它们的值需要被直接序列化为程序集元数据blob)。这就是说,你可以创建一个解决方案,利用类型的,因为那些可以使用

例如:

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

这个语法是完全合法的。读取属性的代码必须获得验证器类型,创建验证器的新实例(如果合适的话,它甚至可以维护一个验证器的缓存,以锁定valicator类型 - 这是一种相当常见的技术),然后调用它。

+0

谢谢你的回答。我已经给Marc提供了接受的答案。但是你使用缓存的建议很有帮助,并且设想这样做是为了节省许多Activator.CreateInstance调用。 – theringostarrs 2009-08-06 01:51:25

5

而且......(我认为这是一个错误的Microsoft)

你不能把一个默认值“空”,但是默认的简单默认值都OK(“假”,“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 2012-12-05 09:12:12

+0

对于user276648,我认为你是对的,他们是相关的,并且解决方案似乎更完整。谢谢 ! – 2012-12-05 13:28:19

+0

实际上,对于您的示例,它可能与编译器错误有关(这意味着您编写Mono时可能会起作用)http://stackoverflow.com/q/8290853 – user276648 2012-12-06 02:32:51

相关问题