是否可以仅在getter或属性的setter上使用Obsolete属性

问题描述 投票:22回答:2

是否可以仅在getter或属性的setter上使用Obsolete属性?

我希望能够做到这样的事情:

public int Id {
    get { return _id;}
    [Obsolete("Going forward, this property is readonly",true)]
    set { _id = value;}
}

但显然不会建立。有没有解决方法允许我将此属性应用于setter?

c#
2个回答
12
投票

我认为这是不可能的,因为由于某种原因,它已被特别禁止用于Obsolete属性。根据围绕属性目标定义的规则,似乎没有任何理由认为Obsolete属性在属性get或set访问器上无效。为了将属性应用于属性集访问器,that attribute must be applicable to either a method, parameter, or return value target。如果你看一下the Obsolete attribute,你会发现“method”是该属性的有效目标之一。

实际上,您可以使用与Obsolete属性with the AttributeUsage attribute相同的有效目标定义自己的属性,并且您将发现可以将其应用于属性get或set访问器,而您不能应用Obsolete属性。

[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属性。 。


7
投票

截至2019年4月2日,我允许将过时属性添加到属性访问器的合并请求被合并到Roslyn(C#编译器)中。

您可以在sharplab上的当前主分支中使用see this in action。它尚未在VS 2019中,但将包含在C#8.0的最终版本中。

这是一个C#8.0功能,因此您必须升级语言版本才能使用它。

感谢Wily博士的学徒,他指出这与他的答案中的其他属性不一致,并激励我在Roslyn上提出一个问题,并实施修复。

这些变化的PR在这里:https://github.com/dotnet/roslyn/pull/32571

© www.soinside.com 2019 - 2024. All rights reserved.