【问题标题】:How to validate a parameter's type in method when using Roslyn使用 Roslyn 时如何在方法中验证参数的类型
【发布时间】:2015-03-24 19:15:19
【问题描述】:

我正在与 Roslyn 进行代码分析,以验证即使我有以下签名

public void MyMethod(object anObject, MyCustomObject customObject);

我只想从 MyCustomObject(第二个)接收一个字符串(第一个)和一个子项作为参数。我对签名没有权力,不能更改。

这是我为评估我的方法所做的(这是一个 sn-p)

    public void OnMethodInvocation(SyntaxNodeAnalysisContext context)
    {
        var invocation= context.Node as InvocationExpressionSyntax;
        var symbol = context.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

        if (symbol?.Name.ToString()== "MyMethod")
        {
            var parameterList = invocation.Parameters;
        }

到目前为止,我可以从属性参数 (symbol.Parameters) 操作我的 IParameterSymbol 对象。我没有得到以下内容:我已经查看了包含我的两个参数的结果 IEnumerable,但是由于方法签名,它希望接收一个对象和一个 MyCustomObject 实例。我不能(目前)确定第一个参数确实是一个对象而不是一个字符串(只是一个例子,可能是其他任何东西)并且当我期待 MyCustomObject 的孩子时,如果我给它一个空值,我想知道它是一个空参数。

我会感谢任何能让我摆脱这种困境的人!

更新

当我进入 ArgumentSyntax 对象时,会得到什么样的信息:

ArgumentSyntax Argument exception
    ContainsAnnotations: false
    ContainsDiagnostics: false
    ContainsDirectives: false
    ContainsSkippedText: false
    Expression: IdentifierNameSyntax IdentifierName exception
    FullSpan: {[550..559)}
    HasLeadingTrivia: false
    HasStructuredTrivia: false
    HasTrailingTrivia: false
    IsMissing: false
    IsStructuredTrivia: false
    KindText: "Argument"
    Language: "C#"
    NameColon: null
    Parent (Microsoft.CodeAnalysis.SyntaxNode): ArgumentListSyntax ArgumentList (exception,exception)
    ParentTrivia: SyntaxTrivia None 
    RawKind: 8638
    RefOrOutKeyword: SyntaxToken None 
    Span: {[550..559)}
    SpanStart: 550

【问题讨论】:

  • 这很令人困惑,因为parameterList 指的是参数列表,而不是参数列表...
  • 我真的不确定你所说的“我已经完成了包含我的两个参数的结果 IEnumerable”是什么意思。很难说出你想要达到的目标。您是否尝试检查第一个 argument 的编译时类型是否为字符串?
  • @JonSkeet 很抱歉,这是我的错误。我不是要谈论 SeparatedSyntaxList,而是谈论 ImmuableArray。我已经在我的帖子中进行了修复。我所说的 IEnumerable 结果的含义如下;在我的测试执行期间,我可以看到我的 ImmuableArray 确实包含我在测试中提供的参数。我没有得到的是如何确保我在 MyMethod 中绝对收到某种类型的参考值
  • 那么听起来你确实想要参数列表,而不是参数列表。毕竟,参数列表说明了实际要传递的内容 - 参数列表每次都相同......
  • @Jcl:编译器知道每个表达式的编译时类型,Roslyn 语义模型很乐意为您提供。 (在运行时,它可能是编译时类型的子类型)

标签: c# code-analysis roslyn


【解决方案1】:

您应该做的是获取参数(不是参数——它们是不同的东西!)并在 ArgumentSyntax 上调用 SemanticModel.GetTypeInfo()。这将为您提供所传递的表达式的类型。从那里你可以做任何你需要的检查。

【讨论】:

  • 我已经尝试过您的解决方案。我发现它仅在显式声明/初始化类型时才有效。使用隐式变量类型时,TypeInfo 的结果将变为 null。不要误会我的意思,我很高兴,因为它在某些情况下对我有帮助,但解决方案并不适用于所有情况。
  • 对不起,Jason,我想我打错字了,但我的分析仪现在可以工作了。谢谢您的帮助! @JasonMalinowski
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多