【问题标题】:Deny use of nameof as parameter of method拒绝使用 nameof 作为方法的参数
【发布时间】:2016-06-23 06:57:56
【问题描述】:

我有这个 C# 函数:

public void MyFunction(string propertyName)
{
    ....
}

该函数将属性名称存储在数据库中以供进一步使用。

我想防止这种方法的用户使用nameof(MyProperty)作为参数,以防止用户在以后的版本中重命名属性时可能出现的情况。

是否可以在一个方法上指定不允许以nameof作为参数调用的方法?

【问题讨论】:

  • 为什么不能通过将“propertyName”与 db 值进行比较来验证它是否有效?
  • 你无法阻止这一点。但是您可以在属性中定义 DataPropertyName 之类的属性,并通过反射在您的函数中检查该属性。
  • 是的,您可以阻止这种情况,但只能在有限的基础上进行。如果您使用 Roslyn 检查所有对 MyFunction() 的调用并查看传入的参数,您可以查看是否存在对 nameof() 的调用。如果有,您可以抛出编译错误。这显然只适用于您控制的代码:分析器必须包含在每个调用 MyFunction() 的项目中。
  • @JeroenVannevel 这听起来很有趣。你有如何做到这一点的例子吗?
  • 您是否熟悉 Roslyn SDK?如果没有,您的第一步是:joshvarty.wordpress.com/learn-roslyn-now

标签: c# .net roslyn c#-6.0 nameof


【解决方案1】:

您需要编写自己的DiagnosticAnalyzer,在context.RegisterSyntaxNodeAction 中订阅SyntaxKind.InvocationExpression。然后检查被调用的方法是否是有问题的方法,然后查看是否有任何参数是nameof 调用。所以大致如下:

context.RegisterSyntaxNodeAction(
    c =>
    {
        var invocation = (InvocationExpressionSyntax)c.Node;
        var symbol = c.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol as IMethodSymbol;
        if (!IsMyMethod(symbol))
        {
            return;
        }
        if (invocation.ArgumentList != null &&
            invocation.ArgumentList.Arguments
                .Select(a => a.Expression)
                .OfType<InvocationExpressionSyntax>()
                .Any(i => i.Expression.ToString() == "nameof"))
        {
            c.ReportDiagnostic(...);
        }
    },
    SyntaxKind.InvocationExpression);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多