如何用roslyn获得一个方法体的il?
我想在我的c#源代码文件中获取一个方法。我已经用roslyn打开了解决方案,并找到如下方法符号
Roslyn.Compilers.Common.ISymbol s=GetMethodSymbolAtPosition (30);
我有一个ISymbol现在怎么样?
不幸的是,IL生成完全隐藏在Roslyn的Emit
调用中。 但是我会给你一个简单的开始。
让我们假设你开始使用现有的编译:
var initial = CSharpCompilation.Create("Existing") .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) .AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(@" namespace Test { public class Program { public static void HelloWorld() { System.Console.WriteLine(""Hello World""); } } }")); var method = initial.GetSymbolsWithName(x => x == "HelloWorld").Single();
其中method
是你的ISymbol
。 然后你可以做以下事情:
// 1. get source var methodRef = method.DeclaringSyntaxReferences.Single(); var methodSource = methodRef.SyntaxTree.GetText().GetSubText(methodRef.Span).ToString(); // 2. compile in-memory as script var compilation = CSharpCompilation.CreateScriptCompilation("Temp") .AddReferences(initial.References) .AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(methodSource, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script))); using (var dll = new MemoryStream()) using (var pdb = new MemoryStream()) { compilation.Emit(dll, pdb); // 3. load compiled assembly var assembly = Assembly.Load(dll.ToArray(), pdb.ToArray()); var methodBase = assembly.GetType("Script").GetMethod(method.Name, new Type[0]); // 4. get il or even execute var il = methodBase.GetMethodBody(); methodBase.Invoke(null, null); }
在更复杂的情况下,您可能需要发出整个/初始编译,并通过reflection获取生成的方法。
请参阅此文章 ,了解如何使用GetMethodBody()
的结果。