var record = SyntaxGenerator.RecordDeclaration("Person")
.WithSemicolonToken();
record.AddParameterListParameters(SyntaxGenerator.StringType.Parameter("Name"));
// record Person;
2. 可以用变量接收更改后的结果
record和record2是不一样的
record代码为record Person;
record2代码为record Person(string Name);
csharp复制代码
var record = SyntaxGenerator.RecordDeclaration("Person")
.WithSemicolonToken();
var record2 = record.AddParameterListParameters(SyntaxGenerator.StringType.Parameter("Name"));
3. 不可变性的集合
SyntaxTree常用的SyntaxList和SeparatedSyntaxList都是不可变的
以下集合初始化和Add都无效
需要特别注意
如果用变量赋值Add的返回值是可以的
csharp复制代码
var list = new SeparatedSyntaxList<ParameterSyntax>
{
SyntaxGenerator.IntType.Parameter("Id")
};
list.Add(SyntaxGenerator.StringType.Parameter("Name"));
Assert.Empty(list);
public static PredefinedTypeSyntax PredefinedType(SyntaxToken keyword)
{
switch (keyword.Kind())
{
case SyntaxKind.BoolKeyword:
case SyntaxKind.ByteKeyword:
case SyntaxKind.SByteKeyword:
case SyntaxKind.IntKeyword:
case SyntaxKind.UIntKeyword:
case SyntaxKind.ShortKeyword:
case SyntaxKind.UShortKeyword:
case SyntaxKind.LongKeyword:
case SyntaxKind.ULongKeyword:
case SyntaxKind.FloatKeyword:
case SyntaxKind.DoubleKeyword:
case SyntaxKind.DecimalKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.CharKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.VoidKeyword: break;
default: throw new ArgumentException(nameof(keyword));
}
return (PredefinedTypeSyntax)Syntax.InternalSyntax.SyntaxFactory.PredefinedType((Syntax.InternalSyntax.SyntaxToken)keyword.Node!).CreateRed();
}
var type = SyntaxFactory.IdentifierName("User");
var user = SyntaxFactory.IdentifierName("user");
var variable = type.Variable(user.Identifier);
3. 限定名类型
就是含命名空间的类名
QualifiedNameSyntax也是TypeSyntax子类,可以表示限定名类型
同样QualifiedNameSyntax也可以表示成员名
Models.User可以表示特定的类
user1.Name自然也可以表示特定的属性
csharp复制代码
var type = SyntaxFactory.IdentifierName("User");
var user = SyntaxFactory.IdentifierName("user1");
var property = SyntaxFactory.IdentifierName("Name");
var @namespace = SyntaxFactory.IdentifierName("Models");
// Models.User
var qualifiedType = type.Qualified(@namespace);
// user.Name
var qualifiedProperty = property.Qualified(user1);
4. 泛型
就是含类型参数的类名
GenericNameSyntax也是TypeSyntax子类,可以表示泛型类型
GenericNameSyntax也可以表示泛型方法
csharp复制代码
// List<int>
var listType = SyntaxGenerator.Generic("List", SyntaxGenerator.IntType);
// GetFieldValue<int>
var method = SyntaxGenerator.Generic("GetFieldValue", SyntaxGenerator.IntType);
三、ParseTypeName的坑
1. 预定义类型
1.1 预定义类型应该使用SyntaxFactory.PredefinedType
ParseTypeName("int")的实际类型PredefinedTypeSyntax
使用SyntaxGenerator.IntType也是不错的
csharp复制代码
var type = SyntaxFactory.ParseTypeName("int");
if (type is PredefinedTypeSyntax predefinedType)
{
var predefinedType0 = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword));
Assert.Equal(predefinedType0.Keyword.Kind(), predefinedType.Keyword.Kind());
}
var type = SyntaxFactory.ParseTypeName("User");
if (type is IdentifierNameSyntax identifierName)
{
var identifierName0 = SyntaxFactory.IdentifierName("User");
Assert.Equal(identifierName0.ToFullString(), identifierName.ToFullString());
}
var type = SyntaxFactory.ParseTypeName("Models.User");
if (type is QualifiedNameSyntax qualifiedName)
{
var qualifiedName0 = SyntaxFactory.IdentifierName("User").Qualified("Models");
Assert.Equal(qualifiedName0.ToFullString(), qualifiedName.ToFullString());
var identifierName = SyntaxFactory.IdentifierName("Models.User");
Assert.Equal(qualifiedName0.ToFullString(), identifierName.ToFullString());
}
var type = SyntaxFactory.ParseTypeName("List<int>");
if (type is not GenericNameSyntax genericName)
{
var genericName0 = SyntaxGenerator.Generic("List", SyntaxGenerator.IntType);
Assert.Equal(genericName0.ToFullString(), genericName.ToFullString());
}
var type = SyntaxFactory.ParseTypeName("System.Collections.Generic.List<int>");
if (type is QualifiedNameSyntax qualifiedName)
{
var qualifiedName0 = SyntaxGenerator.Generic("List", SyntaxGenerator.IntType).Qualified("System.Collections.Generic");
Assert.Equal(qualifiedName0.ToFullString(), qualifiedName.ToFullString());
var genericName = SyntaxGenerator.Generic("System.Collections.Generic.List", SyntaxGenerator.IntType);
Assert.Equal(qualifiedName0.ToFullString(), genericName.ToFullString());
}
var recordDeclaration = SyntaxGenerator.RecordDeclaration("Person")
.WithParameterList(SyntaxFactory.ParameterList())
.WithSemicolonToken();
// record Person();
1.2 null为无参数
默认就是null
csharp复制代码
var recordDeclaration = SyntaxGenerator.RecordDeclaration("Person")
.WithParameterList(null)
.WithSemicolonToken();
// record Person;
var recordDeclaration = SyntaxGenerator.RecordStructDeclaration("Person")
.Public()
.AddParameterListParameters(
SyntaxGenerator.StringType.Parameter("Name")
)
.WithSemicolonToken();
// public record struct Person(string Name);
2. 空方法体的方法
csharp复制代码
var method = SyntaxGenerator.IntType.Method("CreateId")
.Public()
.Partial()
.WithSemicolonToken();
// public partial int CreateId();
3. 空的属性操作器
csharp复制代码
var property = SyntaxFactory.PropertyDeclaration(
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
SyntaxFactory.Identifier("Id"))
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
SyntaxFactory.AccessorDeclaration(SyntaxKind.InitAccessorDeclaration)
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
);
// public int Id { get; set; }
3.1 使用EasySyntax定义空的属性操作器自动加分号
csharp复制代码
var property = SyntaxGenerator.IntType.Property("Id",
SyntaxKind.GetAccessorDeclaration,
SyntaxKind.InitAccessorDeclaration)
.Public();
// public int Id { get; set; }