【问题标题】:Getting a specific method source code from .cs file (at runtime)从 .cs 文件中获取特定方法源代码(在运行时)
【发布时间】:2013-12-02 21:20:27
【问题描述】:

1 -我在光盘上有这个文件内容(cs文件,未编译):

    namespace Test
    {
        using System;
        public class TestClass 
        {
            public string SomeTestMethod(){
                return "test here";
            }
        }
    }

我如何在运行时把方法变成变量:

public string SomeTestMethod(){
    return "test here";
}

例如:SourceCodeParser.GetMothod("path to file","SomeTestMethod");

2 - 可能是访问者成员的内容吗?

   public string SomeMember {
        get {
            return "test here";
        }
    }

【问题讨论】:

  • 您是在谈论为了测试目的而伪造实现吗?在这种情况下,请使用新的 Microsoft Fakes 框架,因为此类本身不可测试。
  • @MichaelPerrenoud - 谢谢,但没有。我想在 html 页面中显示该方法。

标签: c# parsing


【解决方案1】:

Roslyn 是您所需要的。您可以使用nuget 轻松安装它。这是获取方法体的工作代码:

string GetMethod(string filename, string methodName)
{
    var syntaxTree = SyntaxTree.ParseFile(filename);
    var root = syntaxTree.GetRoot();
    var method = root.DescendantNodes()
                     .OfType<MethodDeclarationSyntax>()
                     .Where(md => md.Identifier.ValueText.Equals(methodName))
                     .FirstOrDefault();
    return method.ToString();
}

以及获取属性getter主体的代码:

string GetPropertyGetter(string filename, string propertyName)
{
    var syntaxTree = SyntaxTree.ParseFile(filename);
    var root = syntaxTree.GetRoot();
    var property = root.DescendantNodes()
                       .OfType<PropertyDeclarationSyntax>()
                       .Where(md => md.Identifier.ValueText.Equals(propertyName))
                       .FirstOrDefault();
    var getter = property.AccessorList.Accessors.First(a => a.Kind == SyntaxKind.GetAccessorDeclaration);
    return getter.ToString();
}

【讨论】:

  • 谢谢,看起来不错,这需要 DLL 的路径吗?或源文件的路径?谢谢
  • 解析源文件(.cs),不需要DLL。
  • API已经改变,这段代码不会运行,试试CSharpSyntaxTree.ParseText stackoverflow.com/a/31342480/2257488
  • @Konrad Kokosa 您能否更详细地描述您的解决方案? 描述: - 1. 我在VSNuget 寻找RoslynRoslyn 不存在。 - 2. 我从Nuget 安装了Microsoft.CodeAnalysisMicrosoft.CodeAnalysis 不显示在项目的Links 中。 - 3. 我从 Nuget 安装了 Microsoft.CodeAnalysis.CSharpMicrosoft.CodeAnalysis.CSharp 不会出现在项目的Links 中。 问题。 1. 如何为Console 项目Framework-4.8 实施您的解决方案?
【解决方案2】:

您需要一个可以解析源代码、跟踪代码位置并知道如何在源代码中查找方法(或变量,或任何您关心的命名事物)的工具。有了这个,找到感兴趣的线条就很容易了。这样的工具不容易构建,因为完整语言的解析器不容易构建。查找功能也不容易;参数、命名空间、模板、继承都结合起来使现代语言的名称查找变得非常复杂。

程序转换 (PT) 工具(通常已经有完整的解析器可用)通常通过在内存中构建代表代码的 AST 来做到这一点。然后,给定名称查找规则,按名称在 AST 中查找代码相对简单,并且可以使用此类工具的 prettyprinter 功能将命名实体漂亮地打印到缓冲区/字符串/磁盘文件中,无论您希望它停在哪里.

您不太可能找到一个可以直接从 C# 调用的子例程 PT。您可以从您的程序中调用这样的工具,并让它将字符串作为文本结果/在文件中/通过管道返回您认为最适合进程间通信的任何内容。

如果要显示嵌入在 HTML 页面中的方法文本,通常可以配置 PT 以生成包含漂亮打印实体文本的整个页面。 (通过我的简历查看 JavaSource 浏览器以获取类似的示例)。

【讨论】:

    【解决方案3】:

    .NET Reflection 类不支持反编译为 C#。您可以做的最好的事情是使用MMethodInfo.GetMethodBody() 并在响应中调用MethodBody.GetILAsByteArray()will give you the MSIL 这是 .NET 反射可以给你的最好的。

    要反编译为 C#,您需要一个反编译器 - 其中至少有十几个合法选项。您需要调查一个符合您的要求和预算的方案。

    一个选项是Red Gate's .NET Reflector。尼克哈里森有一个long and thorough article on using .NET Reflector in an application to render source code as HTML

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      相关资源
      最近更新 更多