14

我经常会遇到这样的情况,即我想阻止其他开发人员继续使用方法或类。例如,假设我有两个库方法“A”和“B”,其中“A”是执行某些任务的“旧”方式,而“B”是执行该任务的“新”方式。在许多情况下,A 和 B 有很大的不同,使得使用 A 重构代码以开始使用 B 变得不平凡(例如,需要流过额外的状态)。由于 A 在使用它的情况下有效,因此我不想优先考虑重构。但是,我确实想给我的开发人员一个视觉指示,表明 A 不能用于新代码。

因此,理想情况下,我希望您在使用ObsoleteAttributeWITHOUT 相关的编译器警告/错误引用成员时获得删除线(因为打开它会从 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. 请注意,此问题的文本始终引用该属性。

4

4 回答 4

12

Obsolete属性添加到您的方法将在智能感知中添加删除线。

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

要禁用警告,请在属性前添加:

#pragma warning disable 612, 618

并重新启用:

#pragma warning restore 612, 618

如此处所述,在您的项目文件中而不是在您的代码中放置一个忽略将是一个非常干净的解决方案。

<WarningsNotAsErrors>618</WarningsNotAsErrors>

编辑:另外,请查看@JonHanna 关于使用EditorBrowsable属性的回答。

正如其他人所指出的那样,实际上有 2 个带有过时属性的警告。

编辑:

#pragma warning disable 612, 618
[Obsolete]
#pragma warning restore 612, 618
public class test1
{...

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

在此处输入图像描述

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

test1 test = new test1()会显示删除线。

于 2014-01-14T23:00:08.477 回答
8

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

这里的主要问题是,在编译时没有什么可以区分“旧代码,在我们考虑之前”和“新代码,不应该使用旧习惯”;这一切都只是代码。

关于你唯一能做的就是使用ObsoleteAttribute,然后#pragma warning disable 612, 618在当前用途上使用。与往常一样,#pragma warning不应该在没有评论的情况下存在:

#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)]。该方法根本不会出现在智能感知中,而新方法会鼓励人们使用新方法这一事实(只要库被引用为库而不是解决方案中的项目,或者同一个项目中的类)。

于 2014-01-14T23:03:54.167 回答
6

使用ObsoleteAttribute

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

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

编辑:

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

/// <summary>
/// Please don't use
/// </summary>
public string SomeObsoleteMethod()
{
   // ...
}

根本没有编译器支持。

于 2014-01-14T23:00:01.323 回答
3

就我个人而言,我认为您应该使用ObsoleteAttribute,确保在现有代码中需要的地方使用#pragma(参见此处的示例)来禁用它。

及时修复代码。

于 2014-01-14T23:00:22.663 回答