【问题标题】:How to parse C# code to find the derived class and interfaces of a class如何解析 C# 代码以查找类的派生类和接口
【发布时间】:2010-06-28 20:47:06
【问题描述】:

我正在寻找一种方法来查找基类标识符冒号和已存储到字符串文字中的类的左大括号之间的代码。

我的意思是我有一门课

public class Class : BaseClass
{    
}

它被存储为一个字符串

string classString = "public class Class : BaseClass{}\r\n"

该类肯定会更详细,具有强类型、完全限定的基类和接口的潜力,但我需要一种方法来嗅探冒号和左大括号之间的代码。

假设类不是定义派生约束的泛型 即

public class LinkedList<K,T> : BaseClass
  **where K : IComparable**
{
}

那么可以安全地假设类定义中只有一个冒号,并且很容易找到派生冒号和左大括号。

如果是这样的话我可以这样做

    string baseClassString = classString.Substring(derivationColonIndex + 1, (openCurlyBraceIndex - (derivationColonIndex + 1)))

谁能想到一个更好的方法来保证我得到一个基类的字符串以及冒号和左大括号之间可能存在的任何接口。

为什么我需要这个的背景:类是根据来自数据库的数据生成的,如果数据库中的某些数据发生变化,那么我可能需要更改类字符串中的继承。因此,我将替换基类和接口的现有子字符串。

【问题讨论】:

  • 哇,这听起来真是个坏主意,伙计。我同意 Stefan 的观点,如果你不打算使用反射,这是 RegEx 的工作。神速。
  • 字符串中的文本有什么限制?是否保证是有效的 C#?它可以包含 cmets 吗?它可以包含“预处理器”指令吗?多种类型声明?嵌套类型声明?属性?
  • 都是非常有效的点。 Stefan - 很多时候,在有人给出可行的解决方案之前,我已经自己解决了这个问题。在提出问题 1 年多后,我的问题得到了回答,并且可能忽略了给予某人他们可能应得的荣誉。我知道这是一个社区,它为人们作为聪明的程序员提供声望和荣誉,并允许他们有时能够自吹自擂,虽然我不是真的在这里,但我会更加努力。
  • 至于 RegEx,我希望不要走那条路,因为每次我遇到使用 RegEx 的需要时,我都必须重新学习它,但我想这就是我可能不得不做。
  • Eric - 很可能不会有任何限制。该代码保证是有效的 c#,因为它已经生成。没有 cmets 或预处理器指令。几乎在所有情况下,它都会继承一些父类。我希望这足够简单,不必处理正则表达式或任何太棘手的事情。

标签: c# regex parsing


【解决方案1】:

伙计,你真的应该使用 CodeDOM:

http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx

CodeDOM 提供的类型 代表许多常见类型的源 代码元素。你可以设计一个 构建源代码的程序 使用 CodeDOM 元素的模型 组装一个对象图。这个对象 图可以呈现为源代码 使用 CodeDOM 代码生成器 支持的编程语言。这 CodeDOM 也可以用来编译 将源代码转换为二进制程序集。

我想提请您注意对象图。使用对象图,您应该能够做您需要做的事情。

编辑:抱歉误导,实际上你想要完成的事情与我的建议相反 - 我的错!您可能想查看以下项目,它们提供了从代码构建对象图的功能,而不是从对象图生成代码:

http://csparser.codeplex.com/

http://wiki.sharpdevelop.net/Default.aspx?Page=NRefactory&NS=&AspxAutoDetectCookieSupport=1

【讨论】:

  • 这很酷。我从来没有听说过这个。它可能很难适应我们需要的用途,但它绝对是我会记住的,以备将来使用。谢谢。
  • 如果您从字符串开始,这有什么帮助?据我了解,问题是有一个字符串必须被理解为图形。 CodeDOM 则相反:它将图形转换为字符串。
  • @Eric,你是对的......伙计,我昨天的想法很奇怪。感谢您指出这一点。
【解决方案2】:

你正在进入一个相当深的兔子洞。编写自己的 C# 语言解析器是一项可以让您长时间忙碌的任务,其回报可以提高您作为程序员的技能,但不会让老板皱眉头。

您正在重新发明一个轮子。 Visual Studio 中内置的 DataSet 设计器已经完成了您想做的事情。可以说是走错了轮子,NHibernate 的粉丝肯定会这么想。它们根据 C# 类声明生成 dbase 架构。

考虑到修改一个现有的为 dbase 建模的 C# 类是不必要的,从而挽救您的计划。每次编译时只需从头开始重新生成类。它通常只需要几分之一秒。当发生重大更改时,编译器会尽职尽责地警告您。这就是设置设计器和资源设计器的工作方式。

【讨论】:

  • 基本上我们有一个模式导入实用程序,它将导入我们任何数据库的必要模式信息。然后我们有一个代码生成器,它从数据库中的信息生成数据对象。无需太详细,代码生成器能够随时以 100% 的准确率完全覆盖数据对象。问题在于应用程序开发人员可以向数据对象添加“自定义/附加”代码。
  • 代码生成器检测到这一点,并知道它需要合并代码而不是覆盖它,这样自定义代码才不会丢失。这就是当前问题的来源。这个过程并不完美,并且已经存在了一段时间,我们没有从头开始的选择。除了“重新父”类的能力之外,我们的代码生成器完全按照我们的需要工作。考虑到这只是一个内部工具,我们有更重要的事情可以投入时间。谢谢大家的回复。这些都是非常有用的信息。
  • 开发者应该通过继承自动生成的类来扩展它们。
【解决方案3】:

如果您愿意花一些时间学习它,SharpDevelop 包含一个名为 NRefactory 的 C# 解析器。它从源字符串返回抽象语法树。它可以捕获错误并处理其他语言元素,如 cmets、属性等。

显然这不是一个快速修复,但如果你有时间,它是一个有趣的工具。

【讨论】:

    【解决方案4】:

    有一个ANTLR grammar for C#。也许你可以使用它?

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 2014-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      相关资源
      最近更新 更多