当前位置: 首页 > 编程语言 > C#

使用Roslyn解析-转换-生成代码:我的目标是太高还是太低?与Roslyn分享

时间:2023-04-11 02:22:28 C#

解析/转换/生成代码:我的目标是太高还是太低?(我试图通过从vs生成的设置文件生成接口和包装类来解决Application.Settings/MVVM问题。)我想做的是:我的问题是双重的:如果你想评论MVVM方面,你可以,但这不是问题的要点:)如果你的要求是解析C#源代码,那么我认为Roslyn是一个不错的选择。如果您打算将它用于这部分,我认为将它用于代码生成也是有意义的。使用Roslyn生成代码可能非常冗长(尤其是与CodeDom相比时),但我认为这对您来说不是什么大问题。我认为SyntaxRewriter最适合在代码中进行本地化更改。但是你问的是解析整个类并根据它生成类型,我认为直接查询语法树是最有效的。例如,为类中的所有属性生成只读接口的最简单示例可能如下所示:varoriginalClass=compilationUnit.DescendantNodes().OfType().Single();stringoriginalClassName=originalClass.Identifier.ValueText;varproperties=originalClass.DescendantNodes().OfType();vargeneratedInterface=SyntaxFactory.InterfaceDeclaration('I'+originalClassName).AddMembers(properties.Select(p=>SyntaxFactory.PropertyDeclaration(p.Type,p.Identifier).AddAccessorListAccessors(SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)))).ToArray());我认为Roslyn可以很好地解决这个问题。至于我会使用Roslyn的哪一部分——我可能会在原始类上使用SyntaxWalker,然后使用FluentAPI为要生成的新类型构建新的SyntaxNode。您可以在生成的代码中重用原始树的部分内容(例如参数列表等)。这可能是一个简单的示例:usingSystem;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用Roslyn.Compilers;使用Roslyn.Compilers.CSharp;使用Roslyn.Services;使用Roslyn.Services.CSharp;classProgram{staticvoidMain(string[]args){varsyntaxTree=SyntaxTree.ParseText(@"classC{internalvoidM(strings,inti){}}");}}classWalker:SyntaxWalker{privateInterfaceDeclarationSyntax@interface=Syntax.InterfaceDeclaration("ISettings");privateClassDeclarationSyntaxwrapperClass=Syntax.ClassDeclaration("SettingsWrapper").WithBaseList(Syntax.BaseList(Syntax.SeparatedList(Syntax.ParseTypeName("ISettings"))));privateClassDeclarationSyntax@class=Syntax.ClassDeclaration("SettingsClass").WithBaseList(Syntax.BaseList(Syntax.SeparatedList(Syntax.ParseTypeName("ISettings"))));publicoverridevoidVisitMethodDeclaration(MethodDeclarationSyntaxnode){varparameters=node.ParameterList.Parameters.ToArray();vartypeParameters=node.TypeParameterList.Parameters.ToArray();@interface=@interface.AddMembers(Syntax.MethodDeclaration(node.ReturnType,node.Identifier.ToString()).AddParameterListParameters(参数).AddTypeParameterListParameters(typeParameters));//更多代码也可以将成员添加到类中。关于代码生成问题,我的建议是实际使用内联片段(用CSharpSyntaxTree.ParseText解析)和手动生成的SyntaxNodes,但强烈偏好前者我过去也使用过T4,但我们正在移动由于普遍缺乏集成和功能而远离它们。每个的优点/缺点:RoslynParseTextRoslynSyntaxNodebuild更冗长。可能更难阅读和构建。SyntaxFactoryAPI提供有关有效语法的指导。RoslynQuoter可帮助您将文本代码转换为工厂代码。语法树不一定有效。一旦编写,代码可以更强大。T4模板可能仍然希望使用Roslyn来“反映”输入类型,否则您将遇到System.Reflection和文件锁定等问题。不可发现的API。T4includes,parameters等学习起来会比较混乱。Roslyn代码提示我正在做一些非常相似的事情,我也在使用Roslyn来解析现有的C#代码。但是,我使用T4模板生成新代码。T4模板专为文本生成而设计,并提供了非常好的抽象,因此您可以实际指定看起来像代码的内容,而不是这个疯狂的对象树。以上是C#学习教程:Parsing/converting/generatingcodewithRoslyn:Aremygoalstoohighortoolow?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: