是否可以在运行时修改属性的属性?

Nat*_*ium 4 c# attributes

是否可以在运行时修改属性的属性?

假设我有一些课:

public class TheClass
{
    [TheAttribute]
    public int TheProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

if (someCondition)
{
    // disable attribute. Is this possible and how can this be done?
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 5

不,这是不可能的.您无法在运行时从元数据或一般元数据修改属性值

严格来说,上述情况并非如此.某些API允许允许一些元数据生成和修改.但它们非常特定于场景(ENC,分析,调试),不应用于通用程序.


Mar*_*ell 2

这取决于; 从反思的角度来看:没有。你不能。但是,如果您谈论的是 System.ComponentModel 在数据绑定等方面使用的属性,则可以使用它们TypeDescriptor.AddAttributes附加额外的属性。或涉及自定义描述符的其他客户模型。所以这取决于用例。


在 xml 序列化的情况下,它变得更有趣。首先,我们可以使用有趣的对象模型:

using System;
using System.Xml.Serialization;
public class MyData
{
    [XmlAttribute]
    public int Id { get; set; }
    [XmlAttribute]
    public string Name { get; set; }
    [XmlIgnore]
    public bool NameSpecified { get; set; }

    static void Main()
    {
        var ser = new XmlSerializer(typeof(MyData));

        var obj1 = new MyData { Id = 1, Name = "Fred", NameSpecified = true };
        ser.Serialize(Console.Out, obj1);
        Console.WriteLine();
        Console.WriteLine();
        var obj2 = new MyData { Id = 2, Name = "Fred", NameSpecified = false };
        ser.Serialize(Console.Out, obj2);
    }
}
Run Code Online (Sandbox Code Playgroud)

模式bool {name}Specified {get;set;}(连同bool ShouldSerialize{name}())被识别并用于控制要包含的元素。

另一种选择是使用非默认 ctor:

using System;
using System.Xml.Serialization;
public class MyData
{
    [XmlAttribute]
    public int Id { get; set; }
    public string Name { get; set; }

    static void Main()
    {
        var obj = new MyData { Id = 1, Name = "Fred" };

        XmlAttributeOverrides config1 = new XmlAttributeOverrides();
        config1.Add(typeof(MyData),"Name",
            new XmlAttributes { XmlIgnore = true});
        var ser1 = new XmlSerializer(typeof(MyData),config1); 
        ser1.Serialize(Console.Out, obj);
        Console.WriteLine();
        Console.WriteLine();
        XmlAttributeOverrides config2 = new XmlAttributeOverrides();
        config2.Add(typeof(MyData), "Name",
            new XmlAttributes { XmlIgnore = false });
        var ser2 = new XmlSerializer(typeof(MyData), config2);
        ser2.Serialize(Console.Out, obj);
    }
}
Run Code Online (Sandbox Code Playgroud)

但请注意,如果您使用第二种方法,您需要缓存序列化器实例,因为每次执行此操作时它都会发出一个程序集。我发现第一种方法更简单......