是否可以在运行时修改属性的属性?
让我说我有一些课程:
public class TheClass
{
[TheAttribute]
public int TheProperty { get; set; }
}
有办法做到这一点吗?
if (someCondition)
{
// disable attribute. Is this possible and how can this be done?
}
答案 0 :(得分:5)
不,这是不可能的。您无法在运行时从元数据或一般元数据修改属性值
严格来说,上述情况并非如此。某些API允许允许一些元数据生成和修改。但它们非常特定于场景(ENC,分析,调试),不应用于通用程序。
答案 1 :(得分: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);
}
}
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);
}
}
请注意,如果使用第二种方法,则需要缓存序列化程序实例,因为每次执行此操作时都会发出程序集。我发现第一种方法更简单......
答案 2 :(得分:1)
属性在编译时被烘焙到代码中。在运行时定义新属性的唯一方法是在运行时生成新代码(例如,使用Reflection.Emit)。但是你不能改变现有代码的属性。
答案 3 :(得分:1)
您可以在类中放置Boolean变量来禁用/启用该属性,而不是在运行时禁用它。
答案 4 :(得分:1)
答案 5 :(得分:0)
听起来您想考虑实施IXmlSerializable
答案 6 :(得分:0)
您可以实现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);
}