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

the*_*rrs 55 c# attributes

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

[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }
Run Code Online (Sandbox Code Playgroud)

使用此属性构造函数:

 public PropertyValidationAttribute(IValidatorScheme validator) {
      this._ValidatorScheme = validator;
    }
Run Code Online (Sandbox Code Playgroud)

代码不会编译.如何将对象传递给上面的属性?

编辑:是NullOrEmptyValidatorScheme实现IValidatorScheme.

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

Mar*_*ell 69

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

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
Run Code Online (Sandbox Code Playgroud)

PropertyValidationctor接受一个Type,并Activator.CreateInstance在代码内部使用来创建对象.请注意,理想情况下,您应该在内部存储字符串(AssemblyQualifiedName).

来自ECMA 334v4:

§24.1.3属性参数类型

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

  • 其中以下类型:bool,byte,char, double,float,int,long,short,string.
  • 类型object.
  • 类型System.Type.
  • 枚举类型,前提是它具有公共可访问性,并且嵌套类型(如果有)也具有公共可访问性.
  • 上述类型的一维阵列.

§24.2属性规范

...

E如果以下所有语句都为真,则表达式是attribute-argument-expression:

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


小智 10

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

也就是说,你可以创建一个利用typeofs的解决方案,因为那些可以使用.

例如 :

[PropertyValidation(typeof(NullOrEmptyValidatorScheme))]
public string Name { get; private set; }
Run Code Online (Sandbox Code Playgroud)

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


Eri*_*let 5

还......(我认为这是微软的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
{

}
Run Code Online (Sandbox Code Playgroud)