关于c#:如何将代码标记为“不用于将来使用”

How can you mark code as “not for future use”

我经常遇到这样的情况:我想阻止其他开发人员继续使用方法或类。例如,假设我有两个库方法"a"和"b",其中"a"是执行某项任务的"旧"方法,"b"是执行该任务的"新"方法。在许多情况下,A和B是完全不同的,可以使用A来重构代码,从而开始使用B(例如,需要通过附加状态)。因为a在使用它的情况下是有效的,所以我不想优先考虑重构。不过,我确实想给我的开发人员同事一个直观的指示,即a不能用于新代码中。

因此,理想情况下,我希望在引用带有ObsoleteAttribute的成员时,不带相关的编译器警告/错误(因为打开该选项会从a的所有旧用法中发出数百个错误,我们不打算很快解决这些错误)。这样,如果开发人员使用a编写新的代码行,他或她将立即注意到删除并修复代码以使用b。

在VisualStudio(2012)中有没有任何方法可以获得这样的功能?

编辑:

  • 对于"新旧代码无法区分"的影响,有几条评论。我同意。但是,这不是我想要的,所以让我澄清一下:相反,我想要的是一个代码"过时"(例如删除线)的可视化表示,没有相应的编译器警告或错误。这样,在读取旧代码或编写新代码的过程中,开发人员会立即看到一些过时的东西。即使.NET本机不支持此功能,也可能有一个VS扩展用于此目的?

  • 对于"你不能同时得到警告,也不能同时得到警告"的影响,有几条评论。我本以为我解释了上面的用例,但我会再试一次。我们有一组核心库,它们在构成我们的代码库的各种解决方案中被大量使用。有时,我会更新其中一个库,它为执行某些任务提供了一个新的、更好的API。为了保持向后的兼容性,我不能只删除完成这项任务的旧方法(在许多情况下),因为大量的现有代码依赖于使用旧的API集,而不能简单地重构为使用新的API集。此外,没有迫切的理由这样做;它只会冒险在现有代码中引入错误。但是,我希望通过某种方式向开发人员发出视觉警报,提醒他们应该避免使用某些API,而应该避免使用其他API。这是困难的,因为开发人员倾向于通过读取完成相同任务的现有代码来学习如何完成某些任务。这使得新的API很难传播,因为旧的根深蒂固的API被如此多的现有代码引用。ObsoleteAttribute通过编译器警告实现了这一点,但这些警告只会从数百个旧API的现有使用中产生大量的噪声。这就是我喜欢删除线的原因:它是一种非常直观的东西,但是它只会在开发人员读或写使用过时API的代码时侵入开发人员。下面是一些我想要标记旧API的更改示例:

    • 我们为运行SQL查询引入了一个新的API,它比以前更不冗长、更不古怪、更灵活。很难完全删除旧的API,因为它有许多可能依赖的奇怪行为。但是,我想推动人们朝着新的API发展。
    • 我们有两组内部的单元测试助手API。旧的那个功能非常好,但是它依赖于继承,并且不是非常灵活。较新的是使用属性构建的,并且更灵活。数百个旧的测试仍然使用旧的API运行,但我想推动新测试的编写者使用新的API。
    • 我们的核心库中有一些旧的随机遗留代码,这些代码并不真正适合,但此时很难删除。我想减少对这些类型和方法的新引用的添加。通过这种方式,在某个时候删除它们可能会变得经济有效,因为依赖它们的现有代码会由于正常的搅动而消失。
  • 作为进一步的说明,我认为这个问题的答案能够很好地描述为什么您可能不标记一些过时的东西,即使您不建议在新代码中使用它。

  • 有几条评论/回答简单地指出了ObsoleteAttribute的存在。请注意,此问题的文本始终引用了该属性。


向方法中添加过时的属性将在intellisense中提供删除线。

1
2
3
[ObsoleteAttribute("This property is obsolete. Use NewProperty instead.", false)]
public static string OldProperty
{ get { return"The old property value."; } }

要禁用警告,请将此添加到属性之前:

1
#pragma warning disable 612, 618

重新启用:

1
#pragma warning restore 612, 618

正如这里提到的,在项目文件中而不是在代码中放置一个忽略将是一个非常干净的解决方案。

1
<WarningsNotAsErrors>618</WarningsNotAsErrors>

编辑:另外,查看@jonhana关于使用EditorBrowsable属性的答案。

正如其他人所指出的,实际上有两个用过时属性引发的警告。

编辑:

1
2
3
4
5
#pragma warning disable 612, 618
[Obsolete]
#pragma warning restore 612, 618
public class test1
{...

当您尝试使用test1时,您将得到:

enter image description here

请注意,当您键入var test = new test1()时,删除线不会出现。

但是以东十一〔六〕将显示删除线。


所以你想要一个警告,但是没有任何警告?

这里的主要问题是,在编译时,没有什么东西可以区分"旧代码,在我们更好地考虑它之前"和"新代码,不应该使用旧习惯";这都只是代码。

你唯一能做的就是使用ObsoleteAttribute,然后在当前使用中使用#pragma warning disable 612, 618。像往常一样,#pragma warning不应该没有评论就存在:

1
2
3
#pragma warning 612, 618 //This block of code uses BadOldMethod(), code review planned
/* ... code here */
#pragma warning restore 612, 618

当然,如果有一个很好的理由停止使用它,那么有一个很好的理由可以更快地进行审查,而不是更晚。

编辑:哦,我忘了612和618。您可以将属性设置为引发619而不是618,但这不能被禁用(设置它的主要原因之一是有时适合)。

如果将成员标记为[EditorBrowsable(EditorBrowsableState.Never)],则可能会产生更大的阻碍。这种方法在智能意义上根本不会出现,而新方法会出现,这将鼓励人们朝着新方法发展(只要库被引用为库,而不是作为解决方案中的项目,或同一项目中的类)。


使用ObsoleteAttribute。

1
2
3
4
5
[ObsoleteAttribute("This method is obsolete. Call NewMethod instead.", false)]
public string SomeObsoleteMethod()
{
   // ...
}

最后一个参数(IsError如果设置为true将发出编译错误,否则将发出警告。您可以使用#pragma 612, 618禁用警告。

编辑:

好吧,好吧,我让步了。您想要的解决方案似乎是:

1
2
3
4
5
6
7
/// <summary>
/// Please don't use
/// </summary>
public string SomeObsoleteMethod()
{
   // ...
}

根本不支持编译器。


我个人认为您应该使用ObsoleteAttribute,确保在现有代码中需要时使用#pragma(参见这里的示例)禁用它。

你及时修正了密码。