tags:

views:

253

answers:

6

Is it possible to modify the attribute of a property at runtime?

let's say I have some class:

public class TheClass
{
    [TheAttribute]
    public int TheProperty { get; set; }
}

Is there a way to do this?

if (someCondition)
{
    // disable attribute. Is this possible and how can this be done?
}
+5  A: 

No this is not possible. You cannot modify attribute values from metadata, or metadata in general, at runtime

Strictly speaking the above is not true. There are certain APIs which do allow allow for some metadata generation and modification. But they are very scenario specific, (ENC, profiling, debugging) and should not be used in general purpose programs.

JaredPar
+2  A: 

It depends; from a reflection perspective: no. You can't. But if you are talking about attributes used by System.ComponentModel in things like data-binding, they you can use TypeDescriptor.AddAttributes to append extra attributes. Or other customer models involving custom descriptors. So it depends on the use-case.


In the case of xml serialization, it gets more interesting. Firstly, we can use fun object models:

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);
    }
}

The bool {name}Specified {get;set;} pattern (along with bool ShouldSerialize{name}()) is recognised and used to control which elements to include.

Another alternative is to use the non-default 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);
    }
}

Note though that if you use this second approach you need to cache the serializer instance, as it emits an assembly every time you do this. I find the first approach simpler...

Marc Gravell
I'm talking about attributes to include/exclude some properties when serializing.
Natrium
so, just by addinga property `NameSpecified` the xmlserializer knows whether he needs to serialize Name ? Or am I missing something?
Natrium
+1  A: 

Attributes are baked into code at compilation time. The only way you can define new attributes at run time is to generate new code at runtime (using Reflection.Emit, for example). But you cannot change the attributes of existing code.

Drew Noakes
+1  A: 

You can put Boolean variable in the class to disable/enable the property instead of disabling it at run time.

Wael Dalloul
A: 

Sounds like you want to consider implementing IXmlSerializable

forgot my open id login