首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Roslyn CTP -随机代码修改

Roslyn CTP -随机代码修改
EN

Stack Overflow用户
提问于 2013-05-04 08:45:46
回答 1查看 575关注 0票数 3

我一直在用Roslyn API在遗传编程类型的场景中进行实验。这看起来是一种很好的编程方式,但简单场景的实际实现似乎并不简单,这意味着我可能对如何正确使用此API没有很好的理解。下面是我在实验中尝试修改的一个简单程序:

代码语言:javascript
复制
string treeText = @"using System;
                                using System.Collections.Generic;

                                namespace TestProgram
                                {
                                    class Program
                                    {
                                        static void Main(string[] args)
                                        {
                                            var myVar = 3;
                                            string myString = ""Hello World"";
                                            List<string> stringList = new List<string>();
                                            Console.WriteLine(myString + myVar);
                                            Console.ReadLine();
                                        }
                                    }
                                }";

SyntaxTree tree = SyntaxTree.ParseText(treeText);

var compilation = Compilation.Create("test.exe",
        syntaxTrees: new[] { tree },
        references: new[]
            {
                new MetadataFileReference(typeof(object).Assembly.Location),
                new MetadataFileReference(typeof(Enumerable).Assembly.Location),
            });

        SemanticModel model = compilation.GetSemanticModel(tree);

就像一个简单的例子,假设我以某种方式“随机”决定使用myString实例插入一个新的方法调用。找出我可以从该实例中调用哪些方法的有效方法是什么?那么,从符号信息创建必要的MethodInvocationSyntax (一旦我选择了要使用的特定方法)的最佳方法是什么?我在SemanticModel类上找到了一个名为ResolveOverloads的方法,它出现在我需要结束的地方,但我很难找到该方法所需参数的有效路径。这条路还能走下去吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-04 20:17:16

首先,获取变量的VariableDeclaratorSyntax,例如:

代码语言:javascript
复制
var variable = tree.GetRoot().DescendantNodes()
                   .OfType<VariableDeclaratorSyntax>()
                   .Single(v => v.Identifier.ValueText == "myString");

接下来,从SemanticModel获取此变量的LocalSymbol

代码语言:javascript
复制
var variableSymbol = (LocalSymbol)model.GetDeclaredSymbol(variable);

然后,您可以根据此变量的类型获取可调用的方法列表。您可以简单地获取类型的所有成员,这些成员都是实例方法:

代码语言:javascript
复制
var methods =
    variableSymbol.Type.GetMembers()
                  .OfType<MethodSymbol>()
                  .Where(m => !m.IsStatic && m.MethodKind == MethodKind.Ordinary);

或者,如果您想包含扩展方法,可以使用LookupSymbols()

代码语言:javascript
复制
var methods = model.LookupSymbols(
    variable.GetLocation().SourceSpan.Start, variableSymbol.Type,
    options: LookupOptions.IncludeExtensionMethods)
                   .Where(m => !m.IsStatic);

然后,您可以根据您的逻辑选择一个可用的方法并创建InvocationExpressionSyntax (以下代码假设它是一个无参数方法):

代码语言:javascript
复制
var invocationExpression =
    Syntax.InvocationExpression(
        Syntax.MemberAccessExpression(
            SyntaxKind.MemberAccessExpression,
            Syntax.IdentifierName(variableSymbol.Name),
            (SimpleNameSyntax)Syntax.ParseName(selectedMethod.Name)));

然后,您需要确定在方法中的什么位置添加表达式,以及如何处理其结果(如果有的话)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16369487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档