【问题标题】:Obsolete member field with property accessor (Visual Studio bug)带有属性访问器的过时成员字段(Visual Studio 错误)
【发布时间】:2015-02-24 13:13:49
【问题描述】:

我有一个类,我需要为遗留代码保留一个成员,我需要将其标记为过时,这样新代码就不会使用它(没有收到警告)。

假设这个类看起来像这样:

class MyClass
{
    [Obsolete]
    private string _old = "...";

    [Obsolete]
    public string Old
    {
        get { return _old; }
    }
}

我声明成员字段_old 已过时,以确保类中的新代码不使用该字段。

我还声明属性Old 已过时,以确保类之外的代码不使用该属性。

当我编译这个时,我在属性 getter 中收到一个警告,说 _old 已过时。我认为编译器会默默地忽略这一点,因为属性本​​身已经过时了。

我是否遗漏了某些内容,或者我是否需要为使用过时的成员字段添加#pragma warning disable/restore(即使方法/属性本身被标记为过时)?


我认为编译器会默默地忽略这个”的原因是因为它似乎对过时的类这样做:

[Obsolete]
public class MyObsoleteClass
{
    public string DoSomething()
    {
        // No warning here, since the class itself is obsolete
        return new MyClass().Old;
    }
}

正如@Heinzi 回答的那样:这似乎是由于 Visual Studio 中的一个错误。我已提交有关连接的报告:

https://connect.microsoft.com/VisualStudio/feedback/details/1146809


事实证明,Visual Studio 中的错误不仅限于从属性访问过时的字段。

从过时的方法访问过时的属性不应产生警告:

public class Class2
{
    [Obsolete]
    public string Property { get; set; }

    [Obsolete]
    public void Method()
    {
        this.Property = "value"; // <-- Incorrect warning reported
    }
}

不应该从另一个班级这样做:

public class Class3
{
    [Obsolete]
    public string Property { get; set; }
}

public class Class4
{
    [Obsolete]
    public string Method()
    {
        return new Class3().Property; // <-- Incorrect warning reported
    }
}

有趣的是,它适用于以下类,当添加此类时,其他警告(来自Class4Class2)会神奇地消失。

public class Class5
{
    [Obsolete]
    public void Method()
    {
        // No warning reported here, which is good.
        // This magically makes the other warnings disappear too!
        new Class2().Method();
    }
}

【问题讨论】:

  • 为什么不重构(内部)代码以使用正确的内部字段?然后,您只会收到一次警告(针对该属性),这是 Obsolete-attribute 专为 - 外部使用而设计的。
  • 我需要保持字段不变。遗留代码需要继续使用它。但是,该代码也将被标记为已过时。新代码应该使用新的东西,但旧代码应该仍然存在并使用旧的东西。
  • "我认为编译器会默默地忽略这一点,因为属性本​​身已经过时了。" 是什么让你这么认为?文档中是否有说明这一点的内容?
  • 重新编译项目后,您确定警告仍然存在吗?在我的电脑(VS 2012)上,重新编译后警告消失。 .NET Fiddle 似乎同意:dotnetfiddle.net/CVFN5a(尝试从属性中删除 [Obsolete],您将收到警告,添加它,然后警告消失)。
  • @Heinzi:它有时会消失,但一旦我对代码进行更改,警告就会再次出现。也许只是“后台编译器”产生了这个警告。如果是这样,那就很烦人了……

标签: c# obsolete


【解决方案1】:

你的代码很好,你对Obsolete属性应该如何工作的理解是正确的:如果你在编译后查看“输出”选项卡,你会注意到编译器没有为您的情况输出警告(但如果您按预期从属性中删除 Obsolete 属性,输出警告)。

不过,您是对的,Visual Studio 有时会在对代码进行任意更改后显示警告。这似乎是 Visual Studio 中的一个错误。如果您仍然可以使用最新版本重现它,我建议您在 http://connect.microsoft.com 上提交错误报告。

【讨论】:

  • 我正在使用带有 Update 4 的 Visual Studio 2013。但不确定这是否被认为是最新版本。
  • 我已经检查了命令行编译器csc。那里没有收到任何警告。所以这似乎是你所说的 Visual Studio 中的一个错误。
【解决方案2】:

这将是一个聪明的功能,但我在文档中没有看到任何迹象表明它应该以这种方式工作。另一方面,我不会在私有成员上使用Obsolate 属性(如果该类不是非常大),但我会重构它。我会这样写:

class MyClass
{
    [Obsolete]
    public string Old
    {
        get; private set;
    }
}

然后你只需要把_old的用法改成Old,问题就解决了。

【讨论】:

  • 我需要保留私有成员。既适用于类中的遗留代码,也适用于序列化合同。
  • 对于遗留代码来说,这不会是一个太危险的变化。 (如果没有明确禁止您对其进行更改。)我不熟悉序列化合同,所以很遗憾我无法对此发表评论......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 2010-12-17
  • 2023-04-04
  • 2021-06-02
相关资源
最近更新 更多