Is it possible to change a property attribute at runtime?

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

let's say I have a class:

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

Is there any way to do this?

 if (someCondition) { // disable attribute. Is this possible and how can this be done? } 
+4
source share
7 answers

It depends; in terms of reflection: no. You can not. But if you are talking about the attributes used by System.ComponentModel in things like data binding, you can use TypeDescriptor.AddAttributes to add additional attributes. Or other client models using custom descriptors. So it depends on the use case.


In the case of xml serialization, this becomes more interesting. Firstly, we can use interesting 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 recognized and used to control which elements to include.

Another alternative is to use a 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 that if you use this second approach, you need to cache the serializer instance, as it emits an assembly every time you do it. I find the first approach easier ...

+2
source

No, It is Immpossible. You cannot change attribute values ​​from metadata or metadata in general at run time

Strictly speaking, this is not so. There are specific APIs that allow some generation and modification of metadata. But they are very specific to scenarios (ENC, profiling, debugging) and should not be used in general purpose programs.

+5
source

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

+1
source

You can put a variable in the Boolean class to disable / enable the property, and not disable it at run time.

+1
source

It looks like you want to consider introducing IXmlSerializable

0
source

You can implement IDataErrorInfo, and then check the range in the Validate method.

  public string this[string property] { get { return Validate(property); } } public string Error { get; } protected virtual string Validate(string property) { var propertyInfo = this.GetType().GetProperty(property); var results = new List<ValidationResult>(); var result = Validator.TryValidateProperty( propertyInfo.GetValue(this, null), new ValidationContext(this, null, null) { MemberName = property }, results); if (!result) { var validationResult = results.First(); return validationResult.ErrorMessage; } return string.Empty; } 

In subclass

 protected override string Validate(string property) { Debug.WriteLine(property); if (property == nameof(YourProperty)) { if (_property > 5) { return "_property out of range"; } } return base.Validate(property); } 
0
source

All Articles