10

我正在尝试对nameofa 中的表达式做一些事情CSharpSyntaxWalker,但是,我注意到NameOfExpressionSyntaxAST 中没有。相反,我得到一个InvocationExpressionSyntaxfor whichSemanticModel.GetSymbolInfo返回不匹配的符号,并且调用的表达式是一个IdentifierNameSyntax包含标识符 token "nameof"

因此,为了识别nameof表达式,我会在 中添加一个特殊情况VisitInvocationExpression,查找是否GetSymbolInfo返回任何内容,如果没有,则查找标识符是否为nameof. 但是,这对我来说听起来有点不确定。有没有更好的方法可以将这种检测逻辑转移到解析器?

(PS:我知道这可能是出于向后兼容性的原因解析的;只是想知道是否有用于区分nameof和正常调用的 API。)

4

2 回答 2

5

nameof表达式是编译时常量。您可以使用该事实将其与正常调用区分开来。您可以调用SematicModel.GetConstantValue(). InvocationExpressionSyntax如果它是 a ,您将返回(也返回 true )nameof中的字符串/名称。Optional<object>.ValueHasValue

于 2016-09-05T13:45:46.123 回答
2

我现在确实使用了以下代码段:

if (symbolInfo.Symbol == null &&
    symbolInfo.CandidateSymbols.IsEmpty &&
    symbolInfo.CandidateReason == CandidateReason.None) {
  var identifier = node.Expression as IdentifierNameSyntax;
  if (identifier != null && identifier.Identifier.Kind() == SyntaxKind.IdentifierToken && identifier.Identifier.Text == "nameof") {
    // We have a nameof expression
  }
}

我选择不使用常量值进行检测,以防 C# 8 左右添加了一个不同的运算符,它可能也有一个常量值,但不是nameof. 检测几乎可以准确检测规范所说的用于确定调用是否为nameof表达式的内容:

因为nameof不是保留关键字,所以nameof表达式在调用简单名称时总是在语法上模棱两可nameof。出于兼容性原因,如果名称的名称查找nameof成功,则表达式将被视为invocation_expression——无论调用是否合法。否则它是一个nameof_expression

于 2016-09-07T07:29:30.907 回答