我想解析一个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中。重新创建生成的类时,我希望它跳过生成我已移动到手动编码文件的属性。
因此,反射是不可能的,因为反射会告诉我该属性确实存在,但如果它在一个或另一个文件中定义则不会。
答案 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)