在MSDN,编写自定义属性的示例显示以下奇怪行为
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public virtual string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public virtual string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public virtual bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
}
为什么所有属性都是虚拟的?
答案 0 :(得分:2)
OP上提到的特定MSDN文章的部分是关于属性“继承”的,即如果你有一个类是虚拟的并且用属性注释的类,你添加一个子类并覆盖该方法,子类方法是否应用了属性?这就是继承属性部分中[AttributeUsage(AttributeTargets.Method, Inherited = false)]
的含义。
具体做法是:
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
使用AttributeUsage(AttributeTargets.Method, Inherited = false)]
配置YourAttribute并且MyAttribute具有默认配置。
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
public class YourClass : MyClass
{
// MyMethod will have MyAttribute but not YourAttribute.
public override void MyMethod()
{
//...
}
}
Inherited 的默认值为true。
简而言之,这些属性在文章中是虚拟的,用于描述此功能。
答案 1 :(得分:0)
我怀疑是否有任何具体的理由这样做,因为Attributes在其属性或其他成员上使用或不使用virtual specifiers时效果很好。
public string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
工作也一样好。
但是你无法在派生属性类中override these methods。
例如,这将起作用:
public class WithVirtualPropAttribute : Attribute
{
public virtual String Prop {get; set;}
}
public class DerivedFromWithVirtualPropAttribute : WithVirtualPropAttribute
{
// Compiles ok
public virtual String Prop {get{return "0"} set{}}
}
这不会:
public class WithoutVirtualPropAttribute : Attribute
{
public virtual String Prop {get; set;}
}
public class DerivedFromWithoutVirtualPropAttribute : WithoutVirtualPropAttribute
{
// Compilation error !!!!!!!!!!!!!!!!!!!!!!!!!!
public virtual String Prop {get{return "0";} set{}}
}
对于某些特定情况,它可以是design decision,但总体而言,没有必要这样做。