मेरे पास समाधान में 2 परीक्षण परियोजनाएं हैं।
पहला प्रोजेक्ट ("VDoc") VDocQuery प्रकार की घोषणा करता है।
दूसरी परियोजना ("VDocQueryTest") VDocQuery कंस्ट्रक्टर को कॉल करती है।
मुझे 2 VDocQuery का ITypeSymbol's (प्रत्येक प्रोजेक्ट में से एक) मिलता है, इसकी तुलना करें, लेकिन गलत परिणाम मिलता है।

कदम:
1. पहले ITypeSymbol (VDoc प्रोजेक्ट से सेमेटिकमॉडल के साथ लाइकअप करें। नामस्थानस्पेसएंडटाइप्स () विधि)।
2. VDocQueryTest प्रोजेक्ट से दूसरा ITypeSymbol प्राप्त करें (ObjectCreationExpressionSyntax.GetTypeInfo () प्रकार से)
। 3. ITypeSymbol.Equals (ITypeSymbol) से इसकी तुलना करें।

मुझे सही परिणाम की उम्मीद थी, लेकिन गलत परिणाम मिला।

प्रश्न: एक समाधान के भीतर विभिन्न परियोजनाओं से ITypeSymbols की सही ढंग से तुलना कैसे करें?

कोड उदाहरण:

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();
        }
    }
}
5
Alex Sedow 13 नवम्बर 2015, 00:13

2 जवाब

सबसे बढ़िया उत्तर

मैं दो परियोजनाओं में विभिन्न लक्ष्य रूपरेखाओं का उपयोग करके आपकी समस्या को पुन: उत्पन्न कर सकता हूं। दोनों परियोजनाओं के लिए समान लक्ष्य रूपरेखा निर्धारित करें और फिर आपके मूल समाधान में मिलान प्रकार मिलेंगे।

यदि आप लक्ष्य के ढांचे को नहीं बदल सकते हैं, तो आप अभी भी ITypeSymbol.DeclaringSyntaxReferences की तुलना कर सकते हैं।

3
Tamas 13 नवम्बर 2015, 09:30

जब आपके पास अपने VDocQueryTest प्रोजेक्ट के प्रकार का संदर्भ होता है, तो ISymbol लें और इसे SymbolFinder.FindSourceDefinitionAsync () में पास करें। यह एहसास होगा कि यह अन्य परियोजना से आने वाले मेटाडेटा से एक प्रतीक है और फिर आपको कि परियोजना में मेटाडेटा प्रतीक सौंप देगा। वहां से, आप कर सकते हैं। ईक्वालस ()।

1
Jason Malinowski 12 नवम्बर 2015, 22:08