我试图将对象传递给Attributes构造函数,如下所示:
[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }
使用此属性构造函数:
public PropertyValidationAttribute(IValidatorScheme validator) {
this._ValidatorScheme = validator;
}
代码无法编译。如何将对象传递给上面的属性?
编辑:是NullOrEmptyValidatorScheme实现IValidatorScheme。
错误:错误CS0182:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式。
答案 0 :(得分:68)
属性中的值仅限于简单类型;例如,基本常量(包括字符串)和typeof
...您不能使用new
或其他更复杂的代码。简而言之;你不能这样做。你可以给它类型但是:
[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
即。 PropertyValidation
ctor采用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)。
- 一维数组 属性参数的表达式。
答案 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
{
}