Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果没有SymbolFinder,如何在诊断中获取符号引用?_C#_Roslyn_Roslyn Code Analysis - Fatal编程技术网

C# 如果没有SymbolFinder,如何在诊断中获取符号引用?

C# 如果没有SymbolFinder,如何在诊断中获取符号引用?,c#,roslyn,roslyn-code-analysis,C#,Roslyn,Roslyn Code Analysis,目前我有以下代码: private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax) { foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Var

目前我有以下代码:

    private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
    {
        foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
        {
            var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
            if (declaredSymbol is IFieldSymbol fieldSymbol)
            {
//              SymbolFinder.FindReferencesAsync()
                var b = fieldSymbol.Locations;
//              context.SemanticModel.Compilation.
            }
        }

        return false;
    }
最终,我希望弄清楚dispose方法是否正在访问一次性字段。不幸的是,如果不使用SymbolFinder,我似乎无法找到一种方法来实现这一点,这需要一个解决方案

我使用SymbolFinder做了类似的事情,这是一件容易的事情——但是如何从诊断系统中可用的功能中做到这一点呢


我是否遗漏了一些明显的内容?

您可以简单地使用SemanticModel来分析字段使用的类型,如下所示:

private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
    foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
    {
        var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
        if (declaredSymbol is IFieldSymbol fieldSymbol)
        {
            var isDisposeable = CheckIsTypeIDisposeable(fieldSymbol.Type as INamedTypeSymbol);
            //              SymbolFinder.FindReferencesAsync()
            var b = fieldSymbol.Locations;
            //              context.SemanticModel.Compilation.
        }
    }

    return false;
}

private string fullQualifiedAssemblyNameOfIDisposeable = typeof(IDisposable).AssemblyQualifiedName;
private bool CheckIsTypeIDisposeable(INamedTypeSymbol type)
{
    // Identify the IDisposable class. You can use any method to do this here
    // A type.ToDisplayString() == "System.IDisposable" might do it for you
    if(fullQualifiedAssemblyNameOfIDisposeable == 
        type.ToDisplayString() + ", " + type.ContainingAssembly.ToDisplayString())
    {
        return true;
    }
    if(type.BaseType != null)
    {
        if (CheckIsTypeIDisposeable(type.BaseType))
        {
            return true;
        }
    }
    foreach(var @interface in type.AllInterfaces)
    {
        if (CheckIsTypeIDisposeable(@interface))
        {
            return true;
        }
    }
    return false;
}
private async Task ISMENTIONADDISPECALLASync(SyntaxNodeAnysisContext上下文,FieldDeclarationSyntax FieldDeclarationSyntax)
{
foreach(fieldDeclarationSyntax.Declaration.Variables中的变量variableDeclaratorSyntax)
{
var declaredSymbol=context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
if(declaredSymbol为IFieldSymbol fieldSymbol)
{
var isDisposeable=CheckIsTypeIDisposeable(fieldSymbol.Type为INamedTypeSymbol);
//SymbolFinder.FindReferencesAsync()
var b=字段符号。位置;
//context.SemanticModel.Compilation。
}
}
返回false;
}
私有字符串FullQualifiedAssemblyNameOfiDisposable=typeof(IDisposable).AssemblyQualifiedName;
私有布尔检查类型IDisposeable(INAMEDTYPE符号类型)
{
//标识IDisposable类。您可以使用任何方法在此处执行此操作
//类型.ToDisplayString()==“System.IDisposable”可能适合您
如果(FullQualifiedAssemblyNameOfiDisposable==
type.ToDisplayString()+“,“+type.ContainingAssembly.ToDisplayString())
{
返回true;
}
if(type.BaseType!=null)
{
如果(检查类型IDisposeable(类型.BaseType))
{
返回true;
}
}
foreach(type.AllInterfaces中的var@interface)
{
如果(检查类型IDisPoseable(@interface))
{
返回true;
}
}
返回false;
}

基本上,您会递归地搜索类和基类的所有接口,以找到对应于IDisposeable的类型,该类型应该位于层次结构中的某个位置。

有解决方案有什么问题?@siveajet您不会从诊断级别的诊断内部获得解决方案?如果扫描所有类。analysiscontext保存类的符号。然后,您可以检查它是否实现了
IDisposable
interface@Sievajet手动扫描?没有内置类?这似乎是诊断范围内的基本要求。因为这就是我目前正在做的,但是内置类通常能够做的不止这些。你基本上注册来监听特定类型的节点或符号。并对其进行分析。据我所知,没有任何帮助器类用于此。这就是我正在做的-这是有效的。然而,我正在寻找一种无需手动遍历就能获得符号的方法。恐怕我看不到一种不手动遍历类型的方法
private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
    foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
    {
        var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
        if (declaredSymbol is IFieldSymbol fieldSymbol)
        {
            var isDisposeable = CheckIsTypeIDisposeable(fieldSymbol.Type as INamedTypeSymbol);
            //              SymbolFinder.FindReferencesAsync()
            var b = fieldSymbol.Locations;
            //              context.SemanticModel.Compilation.
        }
    }

    return false;
}

private string fullQualifiedAssemblyNameOfIDisposeable = typeof(IDisposable).AssemblyQualifiedName;
private bool CheckIsTypeIDisposeable(INamedTypeSymbol type)
{
    // Identify the IDisposable class. You can use any method to do this here
    // A type.ToDisplayString() == "System.IDisposable" might do it for you
    if(fullQualifiedAssemblyNameOfIDisposeable == 
        type.ToDisplayString() + ", " + type.ContainingAssembly.ToDisplayString())
    {
        return true;
    }
    if(type.BaseType != null)
    {
        if (CheckIsTypeIDisposeable(type.BaseType))
        {
            return true;
        }
    }
    foreach(var @interface in type.AllInterfaces)
    {
        if (CheckIsTypeIDisposeable(@interface))
        {
            return true;
        }
    }
    return false;
}