查找所有不使用RoslyninheritanceC#类并更改为inheritance自基础对象(类似java)

我正在开发一个小Roslyn项目,包括更改解析树和将更改写回文件。 我已经开始使用独立代码分析器,并希望将其构建为命令行应用程序。 不过,我遇到了一个挑战。 使用: 查找部分使用Roslyn从特定基类派生的类 ,主要使用: https : //github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Syntax-Analysis我创建了这个小项目:

class Program { static void Main(string[] args) { try { if (args.Length < 1) throw new ArgumentException(); SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0])); var root = (CompilationUnitSyntax) tree.GetRoot(); var classes = from ClassDeclarationSyntax in root.DescendantNodesAndSelf() select ClassDeclarationSyntax; foreach (var c in classes) { if (/*Not inheriting*/) { /*Add inherition*/ } } /*Write changes to file*/ } catch (Exception e) { Console.WriteLine("Fatal error ocured."); Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } } } 

作为代码中的注释,我需要检查类是否inheritance某个东西(并选择第二个选项)然后更改解析树,最后将其写入文件,现在我很高兴知道如何检查“不inheritance“只是,虽然第二步和第三步的任何指示也是受欢迎的。 要解析和更改的文件由路径作为程序参数提供:

 if (args.Length < 1) throw new ArgumentException(); SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0])); 


在收到回复的答案的支持下,我想出了工作应用程序。 这是我的代码,可能不完美但有效

 class Program { static void Main(string[] args) { try { if (args.Length < 1) throw new ArgumentException(); SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0])); var root = (CompilationUnitSyntax) tree.GetRoot(); IdentifierNameSyntax iname = SyntaxFactory.IdentifierName("Object"); BaseTypeSyntax bts = SyntaxFactory.SimpleBaseType(iname); SeparatedSyntaxList ssl = new SeparatedSyntaxList(); ssl = ssl.Add(bts); BaseListSyntax bls = SyntaxFactory.BaseList(ssl); bool x = true; while(x) //Way to handle all nodes due to impossibility to handle more than one in foreach { foreach (var c in root.DescendantNodesAndSelf()) { x = false; var classDeclaration = c as ClassDeclarationSyntax; if (classDeclaration == null) continue; if (classDeclaration.BaseList != null) //Inherits continue; else //Not inherits { root = root.ReplaceNode(classDeclaration, classDeclaration.WithBaseList(bls)); x = true; break; } } } if (args.Length > 1) //Write to given file using (var sw = new StreamWriter(File.Open(args[1], FileMode.Open))) { root.WriteTo(sw); } else //Overwrite source using (var sw = new StreamWriter(File.Open(args[0], FileMode.Open))) { root.WriteTo(sw); } } catch (Exception e) { Console.WriteLine("Fatal error ocured."); Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } } } 

ClassDeclarationSyntax具有包含Types BaseList 。 因此,您可以使用以下字段检索有关基类的信息:

  foreach (var c in correctRoot.DescendantNodesAndSelf()) { var classDeclaration = c as ClassDeclarationSyntax; if (classDeclaration == null) { continue; } if (classDeclaration.BaseList?.Types.Count > 0) { Console.WriteLine("This class has base class or it implements interfaces"); } else { /*Add inherition*/ } } 

不幸的是,您需要额外的逻辑来区分您的类具有基类或它只是实现接口。 如果要解决此问题,则需要使用semantical model分析基础对象 (类/接口)以获取有关相应ISymbol信息,或者尝试在syntax tree查找这些节点的声明(如果在您的项目/解决方案中定义了此声明)。

此外,如果要向类添加inheritance,则需要使用SyntaxFactory.SimpleBaseType(...)SyntaxFactory.BaseList(...)将新创建的节点设置为BaseList SyntaxFactory.BaseList(...)