How to compare characters like (ITypeSymbol) from different projects in Roslyn?

I have 2 test projects in solution.
The first project ("VDoc") declares a VDocQuery type.
The second project ("VDocQueryTest") calls the VDocQuery constructor.
I get 2 VDocQuery ITypeSymbol (one from each project), compare it, but get a false result.

Steps:
1. Get the first ITypeSymbol (from the VDoc project using the SemanticModel.LookupNamespacesAndTypes () method).
2. Get the second ITypeSymbol from the VDocQueryTest project (from ObjectCreationExpressionSyntax.GetTypeInfo (). Type)
3. Compare it with ITypeSymbol.Equals (ITypeSymbol).

I expected a true result, but I get a false result.

Question: How to compare ITypeSymbols from different projects within the same solution?

Code example:

91c20f80e86220f22e3bab1a1cea5821.jpg

class Program { static void Main(string[] args) { string solutionPath = @"..\..\..\StaticAnalysis.sln"; MSBuildWorkspace workspace = MSBuildWorkspace.Create(); Solution solution = workspace.OpenSolutionAsync(solutionPath).Result; var vdocProject = FindProjectByName("VDoc", solution); SemanticModel semanticModel = vdocProject.Documents.First().GetSemanticModelAsync().Result; var nsVDocQueryFunctionalTest = (INamespaceOrTypeSymbol)semanticModel.LookupNamespacesAndTypes(0, null, "VDocQueryFunctionalTest").First(); var tVDocQuery = (ITypeSymbol)semanticModel.LookupNamespacesAndTypes(0, nsVDocQueryFunctionalTest, "VDocQuery").First(); TypeInfo ti = GetFromVDocRef(solution); bool result1 = ti.Type.Equals(tVDocQuery); // false, expected = true? //these 2 lines added after Jason Malinowski answer var sVDocQuerySource = SymbolFinder.FindSourceDefinitionAsync(ti.Type, solution).Result; bool result2 = sVDocQuerySource.Equals(tVDocQuery); // false, expected = true? //this line solved the problem, thanks to @Tamas bool result3 = ti.Type.DeclaringSyntaxReferences.FirstOrDefault()?.Equals(tVDocQuery.DeclaringSyntaxReferences.FirstOrDefault()) ?? false; } private static TypeInfo GetFromVDocRef(Solution solution) { var vdocQueryTestProject = FindProjectByName("VDocQueryTest", solution); var vdocQueryTestProjectSemanticModel = vdocQueryTestProject.Documents.First().GetSemanticModelAsync().Result; var compilationUnit = (CompilationUnitSyntax)vdocQueryTestProject.Documents.First().GetSyntaxRootAsync().Result; var ns = (NamespaceDeclarationSyntax)compilationUnit.Members[0]; var cls = (ClassDeclarationSyntax)ns.Members[0]; var method = (MethodDeclarationSyntax)cls.Members[0]; var stat = (ExpressionStatementSyntax)method.Body.Statements[0]; var newExpr = (ObjectCreationExpressionSyntax)stat.Expression; var ti = vdocQueryTestProjectSemanticModel.GetTypeInfo(newExpr); return ti; } static Project FindProjectByName(string projectName, Solution solution) { var project = solution.Projects.SingleOrDefault(p => p.Name == projectName); return project; } } 

VDocQuery.cs:

 using System.Collections.Generic; namespace VDocQueryFunctionalTest { public class VDocQuery { public VDocQuery() { } public void AddFields(string docType, params string[] fields) { } public List<VDoc> Execute() { return null; } } } 

VDocQueryUse.cs:

 using VDocQueryFunctionalTest; namespace VDocQueryTest { static class VDocQueryUse { public static void VDocQueryUseTest() { new VDocQuery(); } } } 
+2
c # roslyn
source share
2 answers

I could reproduce your problem using different target structures in two projects. Set the same target structure for both projects, and then your original solution will find the appropriate types.

If you cannot change the target frameworks, you can still compare ITypeSymbol.DeclaringSyntaxReferences .

+1
source share

When you have a reference to the project type VDocQueryTest, take ISymbol and pass it to SymbolFinder.FindSourceDefinitionAsync (). This will be a symbol from the metadata coming from another project, and then pass you the metadata symbol in that project. From there you can do .Equals ().

+1
source share

All Articles