【问题标题】:Is it possible to return the code of a method (as a string) using delegates in C#?是否可以在 C# 中使用委托返回方法的代码(作为字符串)?
【发布时间】:2012-03-08 04:25:34
【问题描述】:

我会举例说明,因为我不确定我是否正确地问了这个问题(英语不是我的主要语言,而且我还在学习 C#)。

我已经开始使用 Project Euler,并决定创建一个应用程序来跟踪我的结果,并将我的一点 C# 知识用于测试。

在一个特定的类中,我拥有用于​​解决每个问题的静态函数。

static class Answers()
{
  public static string A1(){...}
  public static string A2(){...}
  public static string A3(){...}
  //it goes on
}

问题对象将像这样创建(问题类定义和运行时对象创建)。

class Problem
{
  public string Description;
  public Solution SolutionFinder;

  public Problem(string Desc, Solution Solver)
  {
    this.Description = Desc;
    this.SolutionFinder = Solver;
  }

  public delegate string Solution();

  public string SolveProblem()
  {
    return SolutionFinder.Invoke();
  }
}

这是我的表单创建代码:

{
  ...
  List<Problem> Euler = new List<Problem>();
  Euler.Add(new Problem("Find the sum of all the multiples of 3 or 5 below 1000.", Answers.A1));
  Euler.Add(new Problem("By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.", Answers.A2));
  Euler.Add(new Problem("What is the largest prime factor of the number 600851475143 ?", Answers.A3));
  ...
}

我让课程甚至委托的事情都能正常工作,对此我感到很兴奋。然后我终于决定在一张表格上展示整个事情。 我想展示的是:每当我使用表单解决问题时,问题的描述(已完成)和每种方法的代码(A1、A2 等内部的任何内容)。强>

清楚吗?只是我希望我的表单显示结果以及如何我得到每个问题的解决方案,但不必为了显示而重新输入每个方法的内容 - 方法已经存在。 p>

请不要介意混乱的代码和过度使用公共成员:我知道这是一种不好的做法,但现在我只是想完成这个个人项目,我相信在这里这样做是可以的,因为这只是一个小小的学习经历。

谢谢。

[编辑] 我正在寻找的格式是:

void UpdateForm(int Current)
{
  Problem CurrentProblem = Euler[Current-1];
  string Desc = CurrentProblem.Description;
  string Code = CurrentProblem.SolutionFinder.Method.ReturnType.Name;
  //I got this far, but I need to display more than just the name of the method!
  ...
}

澄清

给定方法:

public static string A1() {
    var answer = 1 + 1;
    return answer.ToString();
}

是否可以在字符串中获取以下行..?

var answer = 1 + 1;
return answer.ToString();

【问题讨论】:

  • 好的,看起来它应该已经可以工作了......这里的确切问题是什么?
  • 您是否要打印出函数的输出及其源代码?
  • @JonSkeet -- 他基本上是在问他是否可以将函数的内容转换为字符串。所以,如果他有一个方法 int MyFunc() { return 1; },他想要一个字符串,上面写着“return 1;”。
  • code for each method (whatever is inside A1, A2, etc. 是什么意思?
  • @ken:你确定吗?除了作为UpdateForm 的参数之外,我在这里看不到任何整数指示...

标签: c# delegates


【解决方案1】:

虽然这不是最好的方法,但如果您通过源文件的属性(右键单击/属性)将“复制到输出目录”值设置为“始终复制”(或“如果较新则复制”),您可以自行解析代码文件,同时针对您的编码风格进行优化。

补充一下,除了源代码转储之外,您是否知道您基本上是在重建 NUnit?

【讨论】:

  • +1 表示“复制到输出目录”。解决他的问题的好主意。
  • 这就是我想要的,至少现在是这样。反射对我来说似乎有点太高级了,浏览文件并获取一些文本是我很舒服的事情。谢谢!
【解决方案2】:

由于在运行时代码是使用 IL(中间语言)编写的,因此您实际上没有可供您使用的可读代码。
无论如何,你可以使用反射来创建一个动态反编译器,或者使用像this onethis one这样的第三方库来反编译这些方法……但我不知道他们是否公开了一些API,我只知道他们是GUI 工具。

【讨论】:

    【解决方案3】:

    您可能会考虑将您的解决方案(源代码)存储在文本文件中。(例如 Problem1.projecteuler、ProblemN.projecteuler)并加载这些文本文件以用于显示和编译/执行插件样式。查看System.Reflection 命名空间并在网络上搜索“C# 插件教程”或类似的内容以开始使用。

    【讨论】:

    • 哦,这看起来很有趣!我的课程还没有达到反思,但我会对此进行一些研究。谢谢。
    【解决方案4】:

    valeriano 您的静态方法可以是 Linq 表达式,然后您可以遍历表达式的每个节点。使用反射也可以,但您需要更多代码

    【讨论】:

    • 忘了说,Linq 表达式适用于 Net 3.5+
    【解决方案5】:

    没有简单的方法从字符串运行代码(即:方法的内容),因为 C# 在其可执行文件启动之前已经编译。

    但是,您可以使用反射和诊断来执行一些技巧,但这需要您在调试模式下运行代码。如果它只是一个小应用程序,这应该不是问题。但大型应用程序在调试模式下运行时会出现性能问题。

    欲了解更多信息:Execute a string in C# 4.0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      相关资源
      最近更新 更多