C# 如何确定分部方法没有实现

C# 如何确定分部方法没有实现,c#,roslyn,C#,Roslyn,鉴于这种情况: partial class Test { partial void FooBar(); } partial class Test { public void Foo() { FooBar(); } } 现在从FooBar()调用中获取SymbolInfo会给我一个IMethodSymbol其中PartialDefinitionPart==null和PartialImplementationPart==null。有没有办法确定没有

鉴于这种情况:

partial class Test
{
    partial void FooBar();
}

partial class Test
{
    public void Foo()
    {
        FooBar();
    }
}

现在从
FooBar()
调用中获取
SymbolInfo
会给我一个
IMethodSymbol
其中
PartialDefinitionPart==null
PartialImplementationPart==null
。有没有办法确定没有部分实现?

部分定义部分的XML文档说明:

如果这是部分方法实现部分,则返回相应的 定义部分。否则为空

PartialImplementationPart

如果这是一个没有主体的分部方法声明,并且该方法是 使用主体实现,返回该实现定义。否则 空


这意味着,如果您正在调用具有实现的分部方法,其符号将具有非-null
PartialImplementationPart
。有趣的是,似乎没有一种简单的方法可以确定一个方法是否是部分的

  • 使用
    部分
    修饰符(
    MethodDeclarationSyntax.修饰符
  • 和(基于svicks答案)都没有
    IMethodSymbol.PartialDefinitionPart
  • IMethodSymbol.PartialImplementationPart
    在没有实现的情况下也不能是部分的
  • 下面的代码演示了如何在给定解决方案中查找所有不带实现的分部方法:

    foreach (var project in solution.Projects)
    {
        foreach (var document in project.Documents)
        {
            var methods = document
                .GetSyntaxRootAsync().Result
                .DescendantNodes()
                .OfType<MethodDeclarationSyntax>()
                .ToList();
    
            var semanticModel = document.GetSemanticModelAsync().Result;
            foreach (var method in methods)
            {
                if (method.Modifiers.All(m => m.ValueText != "partial"))
                    continue;
    
                var methodSymbol = semanticModel.GetDeclaredSymbol(method);
                if (methodSymbol.PartialDefinitionPart == null 
                    && methodSymbol.PartialImplementationPart == null)
                {
                    // found partial method without an implementation!
                }
            }
        }
    }
    
    foreach(solution.Projects中的var项目)
    {
    foreach(project.Documents中的var文档)
    {
    var方法=文档
    .GetSyntaxRootAsync().Result
    .DegeneratNodes()的
    第()类
    .ToList();
    var semanticModel=document.GetSemanticModelAsync().Result;
    foreach(方法中的var方法)
    {
    if(method.Modifiers.All(m=>m.ValueText!=“部分”))
    继续;
    var methodSymbol=semanticModel.GetDeclaredSymbol(方法);
    如果(methodSymbol.PartialDefinitionPart==null
    &&methodSymbol.PartialImplementationPart==null)
    {
    //找到了没有实现的部分方法!
    }
    }
    }
    }
    

    因为你已经有了一个方法符号,并且知道你的方法是局部的,这当然有点过分了,但是我想展示如何在不知道它们是部分的先验知识的情况下找到未实现的部分方法。

    当我试图查找它并在这个roslyn github问题中找到一个实现[1]时,我自己正在使用
    IMethodSymbol
    中的语法对该方法进行编码。那个版本对我不起作用,因为我发现
    DeclaringSyntaxReferences
    只包含一项,即使分部方法有body。我这样做:

        public static bool IsPartialMethod(this IMethodSymbol method, out bool hasEmptyBody)
        {
            if (method.IsDefinedInMetadata())
            {
                hasEmptyBody = false;
                return false;
            }
    
            foreach (var reference in method.DeclaringSyntaxReferences)
            {
                var syntax = reference.GetSyntax();
                if (syntax.Kind() != SyntaxKind.MethodDeclaration)
                    continue;
    
                var node = syntax as MethodDeclarationSyntax;
                if (!node.Modifiers.Any(SyntaxKind.PartialKeyword))
                {
                    hasEmptyBody = false;
                    return false;
                }
            }
    
            hasEmptyBody = method.PartialImplementationPart == null || method.PartialDefinitionPart != null;
            return true;
        }
    
        /// <returns>False if it's not defined in source</returns>
        public static bool IsDefinedInMetadata(this ISymbol symbol)
        {
            return symbol.Locations.Any(loc => loc.IsInMetadata);
        }
    
    public static bool IsPartialMethod(此IMethodSymbol方法,out bool hasEmptyBody)
    {
    if(方法.IsDefinedInMetadata())
    {
    hasEmptyBody=false;
    返回false;
    }
    foreach(方法中的var参考。DeclaringSyntaxReferences)
    {
    var syntax=reference.GetSyntax();
    if(syntax.Kind()!=SyntaxKind.MethodDeclaration)
    继续;
    var node=语法为MethodDeclarationSyntax;
    if(!node.Modifiers.Any(SyntaxKind.PartialKeyword))
    {
    hasEmptyBody=false;
    返回false;
    }
    }
    hasEmptyBody=method.PartialImplementationPart==null | | method.PartialDefinitionPart!=null;
    返回true;
    }
    ///如果未在源中定义,则为False
    公共静态bool在元数据中定义(此为符号)
    {
    返回符号.Locations.Any(loc=>loc.IsInMetadata);
    }
    

    [1]

    您是否尝试过编译?我假设将有一个错误指示未实现的部分方法。如果存在部分实现,符号会是什么样子?@AgentFire在这种情况下没有错误。编译器将跳过对该方法的所有调用。如果没有实现声明,那么编译器将优化定义声明和对方法的所有调用。在语法级别上有一种查找分部方法的方法,分部是一个
    MethodDeclarationSyntax.Modifier
    。尽管如此,我还是同意,符号上没有
    IsPartial
    属性是很奇怪的。