如何将对象传递给属性构造函数

时间:2009-08-05 20:41:01

标签: c# attributes

我试图将对象传递给Attributes构造函数,如下所示:

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

使用此属性构造函数:

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

代码无法编译。如何将对象传递给上面的属性?

编辑:是NullOrEmptyValidatorScheme实现IValidatorScheme。

错误:错误CS0182:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式。

3 个答案:

答案 0 :(得分:68)

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

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]

即。 PropertyValidation ctor采用Type,并在代码中使用Activator.CreateInstance来创建对象。请注意,理想情况下,您应该在内部存储字符串(AssemblyQualifiedName)。

来自ECMA 334v4:

  

§24.1.3属性参数类型

     

位置和命名的类型   属性类的参数是   仅限于属性参数   类型,它们是:

     
      
  • 以下类型之一:boolbytechar,   doublefloatintlongshortstring
  •   
  • 类型object
  •   
  • 类型System.Type
  •   
  • 枚举类型,前提是它具有公共可访问性和   嵌套的类型(如果有的话)   也有公共可访问性。
  •   
  • 以上的一维数组   类型。
  •   

  

§24.2属性规范

     

...

     

表达式E是一个   attribute-argument-expression如果全部   以下陈述是正确的:

     
      
  • E的类型是属性   参数类型(§24.1.3)。
  •   
  • 在编译时,E的值可以是   解决了以下之一:      
        
    • 一个恒定值。
    •   
    • 指定非泛型的typeof-expression(§14.5.11)   类型,封闭的构造类型   (§25.5.2),或未绑定的泛型类型   (§25.5)。
    •   
    • 一维数组   属性参数的表达式。
    •   
  •   

答案 1 :(得分:10)

正如之前的海报所指出的,属性参数中使用的类型受到严格限制(可以理解,因为它们的值需要直接序列化到程序集元数据blob中)。

也就是说,您可以创建一个使用 typeofs 的解决方案,因为可以使用。

例如:

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

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

答案 2 :(得分:5)

另外......(我认为这是一个Microsoft Bug)

您不能将默认值设置为“null”,但默认的简单默认值是ok('false','7','“Test”)。

NExt示例将显示以下错误: 属性参数必须是属性参数类型
的常量表达式,typeof表达式或数组创建表达式 在文件中:... \ CSC

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

[Sample]
public class Toto
{

}