C# 如何将对象传递到属性构造函数中

C# 如何将对象传递到属性构造函数中,c#,attributes,C#,Attributes,我试图将对象传递到属性构造函数,如下所示: [PropertyValidation(new NullOrEmptyValidatorScheme())] public string Name { get; private set; } 使用此属性构造函数: public PropertyValidationAttribute(IValidatorScheme validator) { this._ValidatorScheme = validator; } 代码无法编译

我试图将对象传递到属性构造函数,如下所示:

[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }
使用此属性构造函数:

 public PropertyValidationAttribute(IValidatorScheme validator) {
      this._ValidatorScheme = validator;
    }
代码无法编译。如何将对象传递到如上所述的属性中

编辑:是NullOrEmptyValidatorScheme实现IValidatorScheme


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

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

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
i、 e.
PropertyValidation
ctor采用
类型
,并在代码内使用
Activator.CreateInstance
创建对象。请注意,理想情况下,您应该只在内部存储字符串(
AssemblyQualifiedName

从ECMA 334v4:

§24.1.3属性参数类型

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

  • 以下类型之一:
    bool
    byte
    char
    double
    float
    int
    long
    short
    string
  • 类型
    对象
  • 类型
    System.type
  • 枚举类型,前提是它具有公共可访问性和 嵌套它的类型(如果有) 也有公共可及性
  • 上面的一维数组 类型

§24.2属性规范

表达式
E
是 属性参数表达式(如果全部) 下列陈述中有一项是正确的:

  • E
    的类型是一个属性 参数类型(§24.1.3)
  • 在编译时,E的值可以是 解决以下问题之一:
    • 常数值
    • 指定非通用表达式的表达式类型(§14.5.11) 类型,一个封闭的构造类型 (§25.5.2)或未绑定的通用类型 (§25.5)
    • 一维数组 属性参数表达式

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

也就是说,您可能可以创建一个利用typeof的解决方案,因为可以使用那些

例如:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme))]
public string Name { get; private set; }
这种语法完全合法。读取属性的代码必须获取验证器类型,创建验证器的新实例(如果合适,它甚至可以维护一个对valicator类型键入的验证器缓存-这是一种相当常见的技术),然后调用它。

另外。。。(我认为这是微软的错误)

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

下一个示例将给出以下错误: 属性参数必须是常量表达式、typeof表达式或属性参数类型的数组创建表达式
在文件中:\CSC

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

[Sample]
public class Toto
{

}

编译错误是什么?您确定
NullOrEmptyValidatorScheme
实现了
IValidatorScheme
?就属性语法而言,这是有效的代码,因此它必须与您的对象有关。@kek444-不,它不是。。。我在回复中添加了规范部分…谢谢你的回答。我已经给了马克公认的答案。但您关于使用缓存的建议很有帮助,并且设想这样做是为了从许多Activator.CreateInstance调用中保存。可能与user276648相关:“属性和命名/可选构造函数参数不工作”,我认为您是对的,它们是相关的,解决方案似乎更完整。谢谢实际上,在您的示例中,它可能与编译器错误有关(这意味着您编写的代码在通过Mono编译时可能会起作用)。这是对允许值之一的第二次引用,即枚举,但是实现它并不简单。您知道使用enum的任何示例实现吗?@QueueHammer
[DefaultValue(AnyEnum.SomeValue)]
应该足够了;否则,类似于
[System.Xml.Serialization.xmlement(Form=System.Xml.Schema.XmlSchemaForm.Qualified)]