C# 如何将对象传递给属性构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1235617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass objects into an attribute constructor
提问by theringostarrs
I am attempting to pass objects into an Attributes constructor as follows:
我正在尝试将对象传递给 Attributes 构造函数,如下所示:
[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }
With this attribute constructor:
使用此属性构造函数:
public PropertyValidationAttribute(IValidatorScheme validator) {
this._ValidatorScheme = validator;
}
The code won't compile. How can I pass an object into an attribute as above?
代码不会编译。如何将对象传递给上述属性?
EDIT: Yes NullOrEmptyValidatorScheme implements IValidatorScheme.
编辑:是的 NullOrEmptyValidatorScheme 实现了 IValidatorScheme。
The error: error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
错误:错误 CS0182:属性参数必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式。
采纳答案by Marc Gravell
The values into attributes are limited to simple types; for example, basic constants (including strings) and typeof
... you can't use new
or other more complex code. In short; you can't do this. You can give it the typethough:
属性中的值仅限于简单类型;例如,基本常量(包括字符串)和typeof
...您不能使用new
或其他更复杂的代码。简而言之; 你不能这样做。你可以给它类型:
[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
i.e. the PropertyValidation
ctor takes a Type
, and use Activator.CreateInstance
inside the code to create the object. Note that you should ideally just store the string internally (AssemblyQualifiedName
).
即PropertyValidation
ctor 需要一个Type
, 并Activator.CreateInstance
在代码中使用来创建对象。请注意,理想情况下,您应该只在内部存储字符串 ( AssemblyQualifiedName
)。
From ECMA 334v4:
来自 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.1.3 属性参数类型
属性类的位置和命名参数的类型仅限于属性参数类型,它们是:
- 以下类型之一:
bool
、byte
、char
、double
、float
、int
、long
、short
、string
。- 类型
object
。- 类型
System.Type
。- 枚举类型,前提是它具有公共可访问性,并且嵌套的类型(如果有)也具有公共可访问性。
- 上述类型的一维数组。
and
和
§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.
§24.2 属性规范
...
E
如果以下所有语句都为真,则表达式是属性参数表达式:
- 的类型
E
是属性参数类型(第 24.1.3 节)。- 在编译时,E 的值可以解析为以下之一:
- 一个常数值。
- typeof 表达式(第 14.5.11 节)指定非泛型类型、封闭构造类型(第 25.5.2 节)或未绑定泛型类型(第 25.5 节)。
- 属性参数表达式的一维数组。
回答by Oleg Lvovitch
As previous posters noted, the types use in attribute arguments are quite severely restricted (understandably, because their values need to be serialized directly into the assembly metadata blob).
正如之前的海报所指出的,属性参数中使用的类型受到严格限制(可以理解,因为它们的值需要直接序列化到程序集元数据 blob 中)。
That said, you can probably create a solution that utilizes typeofs, as those canbe used.
也就是说,您可能可以创建一个利用typeofs的解决方案,因为可以使用它们。
For instance :
例如 :
[PropertyValidation(typeof(NullOrEmptyValidatorScheme))]
public string Name { get; private set; }
This syntax is perfectly legal. The code that reads your attributes you have to get the validator type, create a new instance of the validator (it can even maintain a cache of validators keyed on valicator types, if appropriate - this is a fairly common technique), and then invoke it.
这种语法是完全合法的。读取您的属性的代码必须获取验证器类型,创建验证器的新实例(如果合适,它甚至可以维护以验证器类型为键的验证器缓存 - 这是一种相当常见的技术),然后调用它.
回答by Eric Ouellet
Also... (I think it is a Microsoft Bug)
另外...(我认为这是一个Microsoft Bug)
You can't put a default value to "null" but default simple default value are ok ('false', '7', '"Test").
您不能将默认值设置为“null”,但默认的简单默认值是可以的('false'、'7'、'"Test")。
NExt example will give you the following error:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
in file: ... \CSC
NExt 示例将给出以下错误:属性参数必须是
文件中属性参数类型的常量表达式、typeof 表达式或数组创建表达式:...\CSC
public class SampleAttribute : Attribute
{
private string _test;
public SampleAttribute(string test = null)
{
_test = test;
}
}
[Sample]
public class Toto
{
}