[英]How do I get autoproperties on one line when generating code with Roslyn?
我有以下部分代码,用于根据我们用于面向客户的研讨会等的 excel 文件生成数据合同。
private PropertyDeclarationSyntax[] GenerateProperties()
{
var props = new List<PropertyDeclarationSyntax>();
props.Add(SF.PropertyDeclaration(SF.ParseTypeName("IMigrationInformation"), "MigrationInformation")
.AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.OverrideKeyword))
.AddAccessorListAccessors(
SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithBody(SF.Block(SF.ReturnStatement(SF.ObjectCreationExpression(SF.ParseTypeName($"{Form.RegistryName}MigrationInformation")))))
));
foreach (var field in Form.AllDataFields().Where(f => f.FieldTypeInfo != null))
{
props.Add(SF.PropertyDeclaration(SF.ParseTypeName(field.FieldTypeInfo.BackingType.Name), field.SafeName)
.AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken)),
SF.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken))
));
}
return props.ToArray();
}
该代码在一个小问题上运行得非常好。 生成的代码如下所示:
public string VariableName
{
get;
set;
}
我真的希望它看起来像这样:
public string VariableName { get; set; }
如果可能的话,有谁知道如何做到这一点?
我遇到了完全相同的问题。 就我而言,我将代码转换为类似这样的字符串后将其保存到文件中:
private void WriteCodeToFile(NamespaceDeclarationSyntax ns)
{
var codeAsString = ns.NormalizeWhitespace()
.ToFullString();
File.WriteAllText(destFileName, codeAsString);
}
因此,在这种情况下,我只是通过在扩展方法中对字符串运行正则表达式替换来解决它:
private static readonly Regex AutoPropRegex = new Regex(@"\s*\{\s*get;\s*set;\s*}\s");
public static string FormatAutoPropertiesOnOneLine(this string str)
{
return AutoPropRegex.Replace(str, " { get; set; }");
}
然后在将其转换为字符串后调用它:
var codeAsString = ns.NormalizeWhitespace()
.ToFullString()
.FormatAutoPropertiesOnOneLine();
您没有具体说明如何执行文件编写步骤(如果有),因此如果这与您的情况完全无关,我很抱歉没有 100% 以您的问题为目标。 无论如何,其他人可能会从中受益。
您可以实现 CSharpSyntaxRewriter 并将其应用于父 SyntaxNode:
public static class WhitespaceFormatter
{
public static SyntaxNode NormalizeWhitespacesSingleLineProperties(this SyntaxNode node) =>
node.NormalizeWhitespace().SingleLineProperties();
public static SyntaxNode SingleLineProperties(this SyntaxNode node) => new SingleLinePropertyRewriter().Visit(node);
class SingleLinePropertyRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) =>
node.NormalizeWhitespace(indentation: "", eol: " ")
.WithLeadingTrivia(node.GetLeadingTrivia())
.WithTrailingTrivia(node.GetTrailingTrivia());
}
}
使用NormalizeWhitespacesSingleLineProperties
将默认空格应用于除将写入一行的属性声明之外的所有内容。 确保之后不要在您的节点上调用Format
或NormalizeWhitespace()
,因为它会再次使您的属性声明变得混乱。
作为一种简单的解决方案(另一种方式创建节点和具有正确琐事的标记),只需将SyntaxNodeExtensions.NormalizeWhitespace(...)
用于要在一行表示的节点:
...
foreach (var field in Form.AllDataFields().Where(f => f.FieldTypeInfo != null))
{
props.Add(SF.PropertyDeclaration(SF.ParseTypeName(field.FieldTypeInfo.BackingType.Name), field.SafeName)
.AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken)),
SF.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken))
).NormalizeWhitespace(indentation: "", eol: " "));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.