我有一个命令行应用程序,我从一些字符串输入开始,我正在尝试为实现某个接口的所有类添加一个基类。
我已经到了我所在的部分,并检查了基本列表。但我不确定如何
1)检查以确保该类已经从另一个类继承(在这种情况下什么也不做)。
2)从命令行添加提供的类,以便由相关类继承。
举个例子,说我输入了:
-addBaseClass Repository< PocoClass , PocoClass 表> -interface IUserRepository
这符合我的班级声明:
internal class UserRepository : IUserRepository
{
现在我希望它像这样:
internal class UserRepository : Repository<User, UserTable>, IUserRepository
{
我获取匹配类的文件并将其加载到Roslyn:
using (var stream = File.OpenRead(filePath))
{
syntaxTree =
CSharpSyntaxTree.ParseText(SourceText.From(stream), path: filePath);
}
var root = syntaxTree.GetRoot();
//get the initial class declaration
var classDeclaraction = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault();
var baseList = classDeclaraction?.BaseList;
感谢SLaks评论,我能够弄清楚如何添加到基本列表中:
var root = (CompilationUnitSyntax) syntaxTree.GetRoot();
var classDeclaration = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault();
var baseList = classDeclaration?.BaseList;
var newList = classDeclaration.BaseList.Types.Insert(0, SyntaxFactory.SimpleBaseType(
SyntaxFactory.GenericName(
SyntaxFactory.Identifier(baseClass))
.WithTypeArgumentList(
SyntaxFactory.TypeArgumentList(
SyntaxFactory.SeparatedList<TypeSyntax>(GetGenericParameterSyntaxNode(genericParameters))))).NormalizeWhitespace());
var modifierList = classDeclaration.Modifiers.Replace(classDeclaration.Modifiers.FirstOrDefault(x => x.Kind() == SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.InternalKeyword));
var newDeclaration = classDeclaration.WithModifiers(modifierList).WithBaseList(SyntaxFactory.BaseList(newList)).NormalizeWhitespace();
var newDeclarationRoot = SyntaxFactory.CompilationUnit()
.WithMembers(SyntaxFactory.SingletonList<MemberDeclarationSyntax>(newDeclaration)).NormalizeWhitespace();
var updatedRoot = root.ReplaceNode(root.FindNode(classDeclaration.Span), newDeclarationRoot.FindNode(newDeclaration.Span)).NormalizeWhitespace();
所以我现在正在从updatedRoot生成文件。但仍不确定如何检查该类是否已从类继承。 BaseList包含接口和继承的类,我似乎无法在对象图中找到任何区别的东西。
答案 0 :(得分:0)
要查明类声明是否继承了一个类,你可以使用:
if (classDeclaration.BaseList.Types.TryFirst(out var baseType) &&
semanticModel.GetSymbolInfo(baseType.Type).Symbol is ITypeSymbol type &&
type.TypeKind == TypeKind.Class)
{
}
使用SyntaxGenerator
添加基类型可能最简单:
var updated = syntaxGenerator.AddBaseType(
classDeclaration,
SyntaxFactory.ParseName("Repository<User, UserTable>"));
语法生成器为C#执行此操作:
var updated = classDeclaration.WithBaseList(
classDeclaration.BaseList.WithTypes(
classDeclaration.BaseList.Types.Insert(
0,
SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseName("Repository<User, UserTable>")))));
从here省略检查上面的空列表。