gpt4 book ai didi

c# - Roslyn:如果尚未从类继承,如何将泛型类添加到继承的基列表?

转载 作者:太空宇宙 更新时间:2023-11-03 12:15:43 25 4
gpt4 key购买 nike

我有一个命令行应用程序,我从一些字符串输入开始,我正在尝试向所有实现特定接口(interface)的类添加一个基类。

我已经到了上课和检查基本列表的部分。但我不确定该怎么做

1) 检查以确保该类尚未从另一个类继承(在这种情况下什么也不做)。

2) 从命令行添加提供的类以由相关类继承。

举个例子,假设我输入了:

-addBaseClass Repository<PocoClass,PocoClassTable> -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 包括接口(interface)和继承的类,我似乎无法在对象图中找到任何东西来区分。

最佳答案

要确定类声明是否继承了一个类,您可以使用:

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上面省略了对空列表的检查。

关于c# - Roslyn:如果尚未从类继承,如何将泛型类添加到继承的基列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49886608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com