在运行时修改属性的属性是否可能?
假设我有一个类:
public class TheClass
{
[TheAttribute]
public int TheProperty { get; set; }
}
有没有办法做到这一点?
if (someCondition)
{
// disable attribute. Is this possible and how can this be done?
}
在运行时修改属性的属性是否可能?
假设我有一个类:
public class TheClass
{
[TheAttribute]
public int TheProperty { get; set; }
}
if (someCondition)
{
// disable attribute. Is this possible and how can this be done?
}
很抱歉,这是不可能的。您不能在运行时从元数据或元数据中修改属性值。
严格来说,上述说法并不正确。有一些API允许进行某些元数据的生成和修改。但它们非常特定于某些场景(ENC,分析,调试),不应用于通用程序。
这要看具体情况,从反射的角度来看:不能。但如果你在谈论像数据绑定这样的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);
}
}
bool {name}Specified {get;set;}
模式(以及 bool ShouldSerialize{name}()
)被认可并用于控制应包含哪些元素。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);
}
}
NameSpecified
,xmlserializer就知道是否需要序列化名称?或者我漏掉了什么? - Natrium属性在编译时被嵌入到代码中。你唯一能在运行时定义新属性的方式是在运行时生成新代码(例如使用Reflection.Emit)。但你不能改变现有代码的属性。
您可以在类中放置布尔变量来禁用/启用属性,而不是在运行时禁用它。
您可以实现IDataErrorInfo接口,然后在Validate方法中检查范围。
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;
}
在子类中
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);
}