是否可以仅在getter或属性的setter上使用Obsolete属性?
我希望能够做到这样的事情:
public int Id {
get { return _id;}
[Obsolete("Going forward, this property is readonly",true)]
set { _id = value;}
}
但显然不会构建。是否有解决方法允许我将此属性应用于setter?
答案 0 :(得分:12)
我认为这是不可能的,因为由于某种原因,它已被特别禁止使用Obsolete属性。根据围绕属性目标定义的规则,似乎没有任何理由认为Obsolete属性在属性get或set访问器上无效。为了将属性应用于属性集访问器that attribute must be applicable to either a method, parameter, or return value target。如果查看the Obsolete attribute,您会发现“方法”是该属性的有效目标之一。
实际上,您可以使用与过时属性with the AttributeUsage attribute相同的有效目标定义自己的属性,并且您会发现可以将其应用于属性获取或设置访问者,而您无法应用过时属性属性。
[AttributeUsage(AttributeTargets.Method)]
class MyMethodAttribute : Attribute { }
class MyClass
{
private int _Id;
public int Id
{
get { return _Id; }
[MyMethodAttribute] // this works because "Method" is a valid target for this attribute
[Obsolete] // this does not work, even though "Method" is a valid target for the Obsolete attribute
set { _Id = value; }
}
}
如果您尝试在属性集访问器上创建自己的属性并将其应用于那里,那么您可能会注意到错误消息略有不同。您的自定义属性的错误消息将是“属性'YourCustomAttribute'在此声明类型上无效。”,而Obsolete属性的错误消息是“属性'过时'在属性或事件访问器上无效。”错误消息不同的事实使我相信这是一个规则,无论出于何种原因,显式内置到编译器中的Obsolete属性,而不是依赖于应该被应用于Obsolete属性的AttributeUsage属性。
答案 1 :(得分:7)
截至2019年4月2日,我的允许将过时属性添加到属性访问器的合并请求已合并到Roslyn(C#编译器)中。
您可以see this in action在Sharplab上的当前master分支中。它尚未在VS 2019中使用,但将包含在C#8.0的最终版本中。
这是C#8.0的功能,因此您必须升级语言版本才能使用它。
谢谢维利博士的学徒,他指出这与他的回答中的其他属性不一致,并启发了我提出关于罗斯林的问题并实施解决方案。
进行这些更改的PR在这里:https://github.com/dotnet/roslyn/pull/32571