C# 罗斯林可以';找不到IDictionary.Add接口实现成员
为什么以下示例中的Roslyn找不到IDictionary.Add接口成员实现为Dictionary类型 Roslyn正确解析了IDictionary.Add和Dictionary.Add,但在Dictionary类型中找不到实现IDictionary.Add方法 更新 我用正确的代码添加了第二个代码示例 VS2015,罗斯林1.1.1: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
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);
布尔