C# 罗斯林可以';找不到IDictionary.Add接口实现成员

C# 罗斯林可以';找不到IDictionary.Add接口实现成员,c#,roslyn,roslyn-code-analysis,C#,Roslyn,Roslyn Code Analysis,为什么以下示例中的Roslyn找不到IDictionary.Add接口成员实现为Dictionary类型 Roslyn正确解析了IDictionary.Add和Dictionary.Add,但在Dictionary类型中找不到实现IDictionary.Add方法 更新 我用正确的代码添加了第二个代码示例 VS2015,罗斯林1.1.1: using System; using System.Collections.Generic; using System.Linq; using Micros

为什么以下示例中的Roslyn找不到IDictionary.Add接口成员实现为Dictionary类型

Roslyn正确解析了IDictionary.Add和Dictionary.Add,但在Dictionary类型中找不到实现IDictionary.Add方法

更新 我用正确的代码添加了第二个代码示例

VS2015,罗斯林1.1.1:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;

namespace RoslynSymbolsTest
{
    public class InterfaceMemberImplemnentationTest
    {
        public void Run()
        {
            string solutionPath = @"..\..\..\RoslynSymbolsTest.sln";
            MSBuildWorkspace workspace = MSBuildWorkspace.Create();
            Solution solution = workspace.OpenSolutionAsync(solutionPath).Result;
            var project = solution.Projects.Where(p => p.Name == "RoslynSymbolsTest").Single();
            var document = project.Documents.Where(d => d.Name == "InterfaceMemberImplemnentationTest.cs").Single();
            var semanticModel = document.GetSemanticModelAsync().Result;

            // IDictionary.Add
            IMethodSymbol _idictionaryAddMethodSymbol = ResolveMethod(semanticModel, typeof(IDictionary<,>), "Add"); // ok
            // Dictionary.Add
            IMethodSymbol _dictionaryAddMethodSymbol = ResolveMethod(semanticModel, typeof(Dictionary<,>), "Add"); // ok

            var implementationMethodSymbol = _dictionaryAddMethodSymbol.ContainingType.FindImplementationForInterfaceMember(_idictionaryAddMethodSymbol); // null
        }

        private ITypeSymbol ResolveType(SemanticModel semanticModel, Type type)
        {
            string[] names = type.FullName.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

            INamespaceOrTypeSymbol scope = null;
            for (int i = 0; i != names.Count(); ++i)
            {
                string metadataName = names[i];
                string name = metadataName;
                int index = name.IndexOf('`');
                int numberOfGenericTypes = 0;
                if (index != -1)
                {
                    string sNumber = name.Substring(index + 1);
                    if (!int.TryParse(sNumber, out numberOfGenericTypes))
                    {
                        return null;
                    }
                    name = name.Substring(0, index);
                }

                IEnumerable<ISymbol> symbols = semanticModel.LookupNamespacesAndTypes(0, scope, name);
                if (numberOfGenericTypes != 0)
                {
                    symbols = symbols.Where(s => s.MetadataName == metadataName);
                }
                if (symbols.Count() == 1)
                {
                    scope = (INamespaceOrTypeSymbol)symbols.First();
                }
                else
                {
                    scope = null;
                    break;
                }
            }

            return (ITypeSymbol)scope;
        }

        public IMethodSymbol ResolveMethod(SemanticModel semanticModel, Type type, string methodName)
        {
            ITypeSymbol typeSymbol = ResolveType(semanticModel, type);
            if (typeSymbol == null)
            {
                return null;
            }

            var members = typeSymbol.GetMembers(methodName);
            if (members.Length == 1
                && members[0] is IMethodSymbol)
            {
                return members[0] as IMethodSymbol;
            }

            return null;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.MSBuild;
名称空间RoslynSymbolsTest
{
公共类接口MemberImplementTest
{
公开募捐
{
字符串solutionPath=@“.\..\..\RoslynSymbolsTest.sln”;
MSBuildWorkspace=MSBuildWorkspace.Create();
解决方案=workspace.OpenSolutionAsync(solutionPath).Result;
var project=solution.Projects.Where(p=>p.Name==“RoslynSymbolsTest”).Single();
var document=project.Documents.Where(d=>d.Name==“InterfaceMemberImplementTest.cs”).Single();
var semanticModel=document.GetSemanticModelAsync().Result;
//IDictionary.Add
IMethodSymbol _idictionaryAddMethodSymbol=ResolveMethod(semanticModel,typeof(IDictionary),“Add”);//确定
//字典。添加
IMethodSymbol _dictionaryAddMethodSymbol=ResolveMethod(语义模型,类型(字典),“添加”);//确定
var implementationMethodSymbol=\u dictionaryAddMethodSymbol.ContainingType.FindImplementationForInterfaceMember(\u idictionaryAddMethodSymbol);//null
}
私有ITypeSymble ResolveType(SemanticModel SemanticModel,类型类型)
{
string[]names=type.FullName.Split(新[]{.'},StringSplitOptions.RemoveEmptyEntries);
INamespaceOrTypeSymbol范围=空;
for(int i=0;i!=names.Count();++i)
{
字符串metadataName=名称[i];
字符串名称=元数据名称;
int index=name.IndexOf('`');
int numberOfGenericTypes=0;
如果(索引!=-1)
{
string sNumber=name.Substring(索引+1);
if(!int.TryParse(sNumber,out numberOfGenericTypes))
{
返回null;
}
name=name.Substring(0,索引);
}
IEnumerable symbols=semanticModel.LookupNamespacesAndTypes(0,范围,名称);
if(numberOfGenericTypes!=0)
{
符号=符号。其中(s=>s.MetadataName==MetadataName);
}
if(symbols.Count()==1)
{
scope=(inamespaceortypesymble)symbols.First();
}
其他的
{
scope=null;
打破
}
}
返回(ITypeSymbol)范围;
}
公共IMethodSymbol ResolveMethod(SemanticModel SemanticModel,类型类型,字符串方法名)
{
ITypeSymbol typeSymbol=ResolveType(语义模型,类型);
if(typeSymbol==null)
{
返回null;
}
var members=typeSymbol.GetMembers(methodName);
如果(members.Length==1
&&成员[0]是IMethodSymbol)
{
返回成员[0]作为IMethodSymbol;
}
返回null;
}
}
}
固定示例:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;

namespace RoslynSymbolsTest
{
    public class InterfaceMemberImplementationTest
    {
        class MyDisposable : IDisposable
        {
            public void Dispose() { }
        }

        public void Run()
        {
            string solutionPath = @"..\..\..\RoslynSymbolsTest.sln";
            MSBuildWorkspace workspace = MSBuildWorkspace.Create();
            Solution solution = workspace.OpenSolutionAsync(solutionPath).Result;
            var project = solution.Projects.Where(p => p.Name == "RoslynSymbolsTest").Single();
            var document = project.Documents.Where(d => d.Name == "InterfaceMemberImplementationTest.cs").Single();
            var semanticModel = document.GetSemanticModelAsync().Result;

            IMethodSymbol idictionaryAddMethodSymbol = ResolveMethod(semanticModel, typeof(IDictionary<,>), "Add");
            IMethodSymbol idictionaryAddStringObjectMethodSymbol = ResolveMethod(semanticModel, typeof(IDictionary<,>), new Type[] { typeof(string), typeof(object) }, "Add");
            IMethodSymbol idictionaryAddStringStringMethodSymbol = ResolveMethod(semanticModel, typeof(IDictionary<,>), new Type[] { typeof(string), typeof(string) }, "Add");
            IMethodSymbol idictionaryGetItemMethodSymbol = ResolveMethod(semanticModel, typeof(IDictionary<,>), "get_Item");
            IMethodSymbol dictionaryMethodSymbol = ResolveMethod(semanticModel, typeof(Dictionary<,>), "Add");
            IMethodSymbol dictionaryStringObjectMethodSymbol = ResolveMethod(semanticModel, typeof(Dictionary<,>), new Type[] { typeof(string), typeof(object) }, "Add");

            IMethodSymbol idisposableDisposeMethodSymbol = ResolveMethod(semanticModel, typeof(IDisposable), "Dispose");
            IMethodSymbol myDisposableDisposeMethodSymbol = ResolveMethod(semanticModel, typeof(MyDisposable), "Dispose");

            bool result1 = ImplementsInterfaceMember(dictionaryMethodSymbol, idictionaryAddMethodSymbol);
            bool result2 = ImplementsInterfaceMember(dictionaryMethodSymbol, idictionaryGetItemMethodSymbol);

            bool result3 = ImplementsInterfaceMember(dictionaryStringObjectMethodSymbol, idictionaryAddMethodSymbol);
            bool result4 = ImplementsInterfaceMember(dictionaryStringObjectMethodSymbol, idictionaryGetItemMethodSymbol);

            bool result5 = ImplementsInterfaceMember(dictionaryStringObjectMethodSymbol, idictionaryAddStringObjectMethodSymbol);
            bool result6 = ImplementsInterfaceMember(dictionaryStringObjectMethodSymbol, idictionaryAddStringStringMethodSymbol);

            bool result7 = ImplementsInterfaceMember(myDisposableDisposeMethodSymbol, idisposableDisposeMethodSymbol);
        }

        private static bool ImplementsInterfaceMember(IMethodSymbol implementationMethod, IMethodSymbol interfaceMethod)
        {
            if (!IsOpenMethod(interfaceMethod))
            {
                if (implementationMethod.Equals(implementationMethod.ContainingType.FindImplementationForInterfaceMember(interfaceMethod)))
                {
                    return true;
                }
            }
            else
            {
                INamedTypeSymbol interfaceTypeSymbol = interfaceMethod.ContainingType;
                INamedTypeSymbol interfaceConstructedFromTypeSymbol = interfaceTypeSymbol.ConstructedFrom;

                INamedTypeSymbol implementationTypeSymbol = implementationMethod.ContainingType;
                var implementedInterfaces = implementationTypeSymbol.AllInterfaces.Where(i => i.ConstructedFrom.Equals(interfaceConstructedFromTypeSymbol));

                foreach (var implementedInterface in implementedInterfaces)
                {
                    foreach (var implementedInterfaceMember in implementedInterface.GetMembers(interfaceMethod.Name))
                    {
                        if (implementedInterfaceMember.OriginalDefinition.Equals(interfaceMethod))
                        {
                            var exactImplementedInterfaceMember = implementationMethod.ContainingType.FindImplementationForInterfaceMember(implementedInterfaceMember);
                            if (implementationMethod.Equals(exactImplementedInterfaceMember))
                            {
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }

        private static bool IsOpenMethod(IMethodSymbol method)
        {
            bool result = method.OriginalDefinition.Equals(method);
            return result;
        }

        private ITypeSymbol ResolveType(SemanticModel semanticModel, Type type)
        {
            string[] names = type.FullName.Split(new[] { '.', '+' }, StringSplitOptions.RemoveEmptyEntries);

            INamespaceOrTypeSymbol scope = null;
            for (int i = 0; i != names.Count(); ++i)
            {
                string metadataName = names[i];
                string name = metadataName;
                int index = name.IndexOf('`');
                int numberOfGenericTypes = 0;
                if (index != -1)
                {
                    string sNumber = name.Substring(index + 1);
                    if (!int.TryParse(sNumber, out numberOfGenericTypes))
                    {
                        return null;
                    }
                    name = name.Substring(0, index);
                }

                IEnumerable<ISymbol> symbols;
                if (i == 0)
                {
                    symbols = semanticModel.LookupNamespacesAndTypes(0, scope, name);
                }
                else
                {
                    symbols = scope.GetMembers(name).Where(m => m.Kind == SymbolKind.Namespace || m.Kind == SymbolKind.NamedType);
                }

                if (numberOfGenericTypes != 0)
                {
                    symbols = symbols.Where(s => s.MetadataName == metadataName);
                }
                if (symbols.Count() == 1)
                {
                    scope = (INamespaceOrTypeSymbol)symbols.First();
                }
                else
                {
                    scope = null;
                    break;
                }
            }

            return (ITypeSymbol)scope;
        }

        private ITypeSymbol ResolveType(SemanticModel semanticModel, Type type, params Type[] typeParameters)
        {
            ITypeSymbol typeSymbol = ResolveType(semanticModel, type);
            if (typeSymbol == null)
            {
                return null;
            }

            ITypeSymbol[] typeParametersSymbols = new ITypeSymbol[typeParameters.Length];
            for (int i = 0; i != typeParameters.Length; ++i)
            {
                ITypeSymbol typeParameterSymbol = ResolveType(semanticModel, typeParameters[i]);
                if (typeParameterSymbol == null)
                {
                    return null;
                }
                typeParametersSymbols[i] = typeParameterSymbol;
            }

            INamedTypeSymbol constructedTypeSymbol = ((INamedTypeSymbol)typeSymbol).Construct(typeParametersSymbols);
            return constructedTypeSymbol;
        }

        public IMethodSymbol ResolveMethod(SemanticModel semanticModel, Type type, string methodName)
        {
            ITypeSymbol typeSymbol = ResolveType(semanticModel, type);
            if (typeSymbol == null)
            {
                return null;
            }

            var members = typeSymbol.GetMembers(methodName);
            if (members.Length == 1
                && members[0] is IMethodSymbol)
            {
                return members[0] as IMethodSymbol;
            }

            return null;
        }

        public IMethodSymbol ResolveMethod(SemanticModel semanticModel, Type type, Type[] typeParameters, string methodName)
        {
            ITypeSymbol typeSymbol = ResolveType(semanticModel, type, typeParameters);
            if (typeSymbol == null)
            {
                return null;
            }

            var members = typeSymbol.GetMembers(methodName);
            if (members.Length == 1
                && members[0] is IMethodSymbol)
            {
                return members[0] as IMethodSymbol;
            }

            return null;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.MSBuild;
名称空间RoslynSymbolsTest
{
公共类接口MemberImplementationTest
{
类别:IDisposable
{
public void Dispose(){}
}
公开募捐
{
字符串solutionPath=@“.\..\..\RoslynSymbolsTest.sln”;
MSBuildWorkspace=MSBuildWorkspace.Create();
解决方案=workspace.OpenSolutionAsync(solutionPath).Result;
var project=solution.Projects.Where(p=>p.Name==“RoslynSymbolsTest”).Single();
var document=project.Documents.Where(d=>d.Name==“InterfaceMemberImplementationTest.cs”).Single();
var semanticModel=document.GetSemanticModelAsync().Result;
IMethodSymbol idictionaryAddMethodSymbol=ResolveMethod(语义模型,类型化(IDictionary),“添加”);
IMethodSymbol idictionaryAddStringObjectMethodSymbol=ResolveMethod(语义模型,类型化(IDictionary),新类型[]{typeof(字符串),类型化(对象)},“添加”);
IMethodSymbol idictionaryAddStringStringMethodSymbol=ResolveMethod(语义模型,类型化(IDictionary),新类型[]{typeof(string),typeof(string)},“添加”);
IMethodSymbol idictionaryGetItemMethodSymbol=ResolveMethod(语义模型,类型化(IDictionary),“获取项”);
IMethodSymbol dictionaryMethodSymbol=ResolveMethod(语义模型,类型(字典),“添加”);
IMethodSymbol dictionaryStringObjectMethodSymbol=ResolveMethod(语义模型,typeof(字典),新类型[]{typeof(字符串),typeof(对象)},“添加”);
IMethodSymbol idisposableDisposeMethodSymbol=ResolveMethod(语义模型,类型(IDisposable),“Dispose”);
IMethodSymbol myDisposableDisposeMethodSymbol=ResolveMethod(语义模型,类型(MyDisposable),“Dispose”);
bool result1=实现接口成员(dictionaryMethodSymbol、idictionaryAddMethodSymbol);
bool result2=实现接口成员(dictionaryMethodSymbol、idictionaryGetItemMethodSymbol);
bool result3=实现接口成员(dictionaryStringObjectMethodSymbol、idictionaryAddMethodSymbol);
布尔