【问题标题】:How to show a specific hint within Visual Studio如何在 Visual Studio 中显示特定提示
【发布时间】:2015-09-01 12:57:15
【问题描述】:

我目前正在努力改善我的编码感觉,因此我开始为我正在使用的类型添加一些扩展方法。


我发现,我经常使用相同的属性执行相同的操作。

我想在有人打电话给ReplaceNewLine("|")时显示这个提示:

您要删除的字符是|。请改用不带任何属性的 RemoveNewLine() 扩展名。

我尝试使用 [Obsolete(...)] 属性,但每次调用该函数时都会显示。

我的问题是:如何根据我在 Visual Studio 中的输入显示特定提示?

代码:

public static class StringExtension
{
    public static string ReplaceNewLine(this string s)
    {
        return s.Replace("|", Environment.NewLine);
    }

    // show hint if c is |
    public static string ReplaceNewLine(this string s, string c)
    {
        return s.Replace(c, Environment.NewLine);
    }
}

同位:

  • 当然,在显示时提示可能有Obsolete 代码(0618/CS0618),但这对我来说并不重要。我只想得到显示的提示!
  • 我正在与C# 6.0.NET 4.6Visual Studio 2015 RC 合作。

【问题讨论】:

  • ReSharper 插件可以作为解决方案吗?
  • @Thomas 不,很抱歉,ReSharper 插件对我来说不是一个合适的解决方案,因为我不使用它。它应该完全使用 Visual Studio 中的代码完成,而无需添加/安装任何其他程序。不过还是谢谢...
  • 您是否尝试过围绕 2 个私有方法使用 Wrapper 方法,其中一个已过时,但只有在输入为“|”时才会被调用?
  • 方法的名称应该暗示它的作用。将标准使用规则与代码的内部实现混合使用是一个非常糟糕的主意。

标签: c# visual-studio visual-studio-2015 hint obsolete


【解决方案1】:

在 Visual Studio 2015 中,这可以使用 Roslyn 诊断(和可选的修复)来实现。新的 Visual Studio 2015 代码编辑器在底层使用 Roslyn 来完成所有解析,代码分析、度量和重构引擎现在基于它。

这种检查的示例实现是given on the Roslyn github page。一个完整的实现对于 StackOverflow 上的答案来说有点多,因为它需要经过许多步骤并且相当于一个完整的教程,但这个完整的教程是 something similar is given here。并且可能是您工作的基础。 (稍后再问其他问题)。 standard rules that ship with the product can be found in the Roslyn GitHub as well 的代码。

这段代码应该可以让你非常接近,但我还没有测试过。根据 Roslyn SDK 教程创建标准诊断和修复,并将 InitializeAnalyzeNode 方法替换为(将命名空间替换为您自己的):

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);
}

private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
{
    InvocationExpressionSyntax invocationExpression = context.Node as InvocationExpressionSyntax;
    IMethodSymbol methodSymbol = context.SemanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol;

    if (
        methodSymbol != null
        && methodSymbol.Name == "ReplaceNewline" 
        && methodSymbol.ContainingNamespace.Name == "MySampleFix"
        && methodSymbol.OriginalDefinition.Parameters.Length == 1)
    {
        if (invocationExpression.ArgumentList.Arguments.Count() == 1)
        {
            LiteralExpressionSyntax arg =
                invocationExpression.ArgumentList.Arguments[0].Expression as LiteralExpressionSyntax;

            if (arg != null && arg.Token.ValueText == "|")
            {
                Diagnostic.Create(Rule, invocationExpression.GetLocation());
            }
        }
    }
}

如果您想使某些东西向后兼容旧版本的 Visual Studio,您可以选择编写自定义代码分析规则。这个example rule 将输入用于对Regex.MatchRegex.Replace 的调用,并在它无法编译时发出警告。当它是一个常量字符串时,发出警告会更简单。

Resharper 和 CodeRush 等 Visual Studio 扩展提供了一个 SDK,它可以做类似于 FxCop 的事情,但它们像 Roslyn 一样嵌入到 IDE 中。您可以选择采用这种方法。

如果您希望代码编辑器中的某些内容不使用任何扩展或自定义,那么在 codedoc 中添加 <remark /> 即可。在最坏的情况下,您可以在该方法中输入 Debug.Assert(input != "|");,这样开发人员将收到早期警告(在开发/调试时),他们正在错误地使用您的 API。

【讨论】:

  • 如果你能提供一个例子,那就完美了!
  • 我还不是 Roslyn 规则之王,提供的示例可能不是最好的。它应该足以让您开始并提出后续问题。
  • 不客气。如果您有完整的解决方案或找到所需的更改,请不要犹豫更新答案。
【解决方案2】:

我认为不可能,只有例外

强调评论

:)

/// <summary>
/// Replace specific char with <see cref="Environment.NewLine"/>
/// </summary>
/// <param name="s">input</param>
/// <param name="c">If the char is "|", use the extension method without any parameter instead (<see cref="StringExtension.ReplaceNewLine()" />).</param>
/// <returns>something with maybe new lines.</returns>
public static string ReplaceNewLine(this string s, string c) {...}

除了#warning msg(和#pragma),我不知道在纯Visual Studio 中产生提示的任何其他方式,但它们仅由预定义的构建参数(如#IF DEBUG 等)有条件,并且它们直接进入错误列表。

顺便说一句,只是为了好玩:您可以通过添加默认值来解决您的示例

public static class StringExtension
{
    public static string ReplaceNewLine(this string s, string c = "|")
    {
        return s.Replace(c, Environment.NewLine);
    }
}

编辑:jessehouwing 的答案要好得多,整个答案或多或少是关于 大力士 的笑话 :)

【讨论】:

  • 小心“默认值”,因为它们非常邪恶。默认值实际上已编译到调用二进制文件中,如果您决定稍后更改默认值,则需要重新编译调用该方法的所有程序集以使用新值。
  • 是的,这样它是编译器功能而不是语言功能。这不好 ;).
【解决方案3】:

使用单引号

return s.Replace('|', Environment.NewLine);

【讨论】:

  • 你完全误解了这个问题。
猜你喜欢
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
相关资源
最近更新 更多