从c#源文件中提取属性名称

时间:2010-06-10 13:36:43

标签: c#

我想解析一个c#文件。我唯一想要的是确定它是否包含具有特定名称的属性;只是一个简单的真/假响应。或者更确切地说,因为我在每次运行中检查多个属性,所以提取属性名称列表可能会有所帮助

我认为我可以使用CodeDomProvider功能创建一个优雅的解决方案(f#示例):

use reader = new StreamReader(existingFile)
let codeProvider = new CSharpCodeProvider()
let codeUnit = codeProvider.Parse(reader)

不幸的是,Parse没有实现CSharpCodeProvider功能。有没有办法从源文件中获取CodeCompileUnit?或者还有另一种优雅的方式吗? (我原本希望避免使用正则表达式)?

编辑: 我将使用它来自动生成代码。基本上,我将在文件xyz.partial.cs中生成一个部分类。这将生成一个骨架属性。但是,如果我想更改属性的实现,我将剪切该属性并将其粘贴到手动编码的xyz.cs中。重新创建生成的类时,我希望它跳过生成我已移动到手动编码文件的属性。

因此,反射是不可能的,因为反射会告诉我该属性确实存在,但如果它在一个或另一个文件中定义则不会。

6 个答案:

答案 0 :(得分:0)

找到了这个,但没有经验 - 好的或坏的 - 用它:http://www.codeproject.com/KB/recipes/codedomparser.aspx

答案 1 :(得分:0)

有时RegEx是唯一优雅的解决方案。这应该是你正在寻找的。它将为您提供代码文件中每个属性的名称,仅此而已:

(?:"(?:(?:(?:\\.)|[^"\\\r\n])*)"|'(?:(?:(?:\\.)|[^'\\\r\n])*)'|@"(?:(?:(?:"")|[^"])*)")|(?:(?://.*)|(?:/\*(?:(?:[^*]|\*(?!/))*)\*/))|(?:[\w?<>]\s+(\w+)\s*\{\s*(?:get|set)\s*[{;])

它不会匹配注释或字符串中的类似代码,只需要很小的修改就可以返回属性的类型。该名称显示在capture \ 1中,但如果不是真正的匹配则为空。

答案 2 :(得分:0)

编辑2:根据添加的信息,我会说您最好编译手工编码的课程然后反映该课程。然后,您可以生成部分类文件的代码。

编辑:我做了更多的研究,看起来你运气不好。 CodeDom不能用于解析代码。 http://blogs.msdn.com/b/bclteam/archive/2005/03/16/396929.aspx

有关如何在MSDN上创建CSharpCodeProvider实例的示例。

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CodeCompileUnit ccu = provider.Parse(reader);

然后,您可以导航CodeCompileUnit(有关CodeCompileUnit的更多文档)。

希望它有所帮助。

答案 3 :(得分:0)

我认为你可以通过在运行时使用PropertyInfo来解决这个问题。它使用反射来返回类型的所有信息。要从类型中获取所有属性名称,请尝试以下操作:

void GetMeTheProperties(object source)
{
    Type sourceType = source.GetType();

    foreach (PropertyInfo sourceProperty in sourceType.GetProperties())
    {
        int i = 1;
        Console.WriteLine("Property {0}: {1}", i, sourceProperty.Name;
    }
}

您还可以通过类似的方法确定特定命名属性是否属于某种类型:

bool PropertyExists(string propertyName, object source)
{
    Type sourceType = source.GetType();
    return (from var s in sourceType.GetProperties() select s).Where(i => i.Name == propertyName).Any();
}

答案 4 :(得分:0)

您要生成代码的文件是否已编译?如果是这样,您可以尝试创建一个属性以添加到不应复制的所有属性。然后,您可以使用反射来读取属性并跳过这些属性。

internal class DoNotCopyAttribute: Attribute{}

// then add this to Odhran's GetMeTheProperties
bool skip=false;
foreach (System.Attribute attr in System.Attribute.GetCustomAttributes(sourceProperty)) {
  if (attr is DoNotCopyAttribute){ skip=true; break; }
}
if(skip) continue;

答案 5 :(得分:0)