Skip to content

SyntaxFactory 高级用法 - Part 1

本文档介绍 SyntaxFactory 的高级用法和技巧(第一部分)。

📋 文档信息

  • 难度级别: 高级
  • 预计阅读时间: 20 分钟

SyntaxFactory 楂樼骇

馃搵 鏂囨。淇℃伅

闅惧害: 馃敶 楂樼骇
棰勮闃呰鏃堕棿: 35 鍒嗛挓
鍓嶇疆鐭ヨ瘑:

  • SyntaxFactory 鍩虹
  • C# 娉涘瀷鍜岀壒鎬?
  • 璁捐妯″紡鍩虹

閫傚悎浜虹兢:

  • 闇€瑕佺敓鎴愬鏉備唬鐮佺粨鏋勭殑寮€鍙戣€?
  • 楂樼骇婧愮敓鎴愬櫒寮€鍙戣€?
  • 浠g爜鐢熸垚宸ュ叿鏋舵瀯甯?

馃搵 蹇€熷鑸?

绔犺妭闅惧害闃呰鏃堕棿閾炬帴
澶嶆潅缁撴瀯鐢熸垚馃敶10 鍒嗛挓鏌ョ湅
娉涘瀷绫荤敓鎴?馃敶5 鍒嗛挓[鏌ョ湅](#鐢熸垚娉涘瀷绫?
鐗规€х敓鎴?馃煛5 鍒嗛挓鏌ョ湅
鎺ュ彛鍜屾灇涓?馃煛5 鍒嗛挓鏌ョ湅
鐪熷疄浣跨敤鍦烘櫙馃敶10 鍒嗛挓鏌ョ湅

馃幆 姒傝

鏈枃妗d粙缁?SyntaxFactory 鐨勯珮绾т娇鐢ㄦ妧鏈紝鍖呮嫭澶嶆潅缁撴瀯鐨勭敓鎴愩€佹硾鍨嬬被銆佺壒鎬с€佹帴鍙g瓑銆?

**鏈枃妗f兜鐩?*:

  • 澶嶆潅绫荤粨鏋勭殑鐢熸垚
  • 娉涘瀷绫诲拰鏂规硶鐨勭敓鎴?
  • 鐗规€э紙Attributes锛夌殑鐢熸垚
  • 鎺ュ彛鍜屾灇涓剧殑鐢熸垚
  • 鐪熷疄椤圭洰涓殑浣跨敤鍦烘櫙

鍏稿瀷搴旂敤鍦烘櫙:

  • DTO 绫昏嚜鍔ㄧ敓鎴?
  • Builder 妯″紡浠g爜鐢熸垚
  • API 瀹㈡埛绔唬鐮佺敓鎴?
  • 澶嶆潅鐨勪唬鐮侀噸鏋勫伐鍏?

澶嶆潅缁撴瀯鐢熸垚

鐢熸垚绫?

csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勭被
/// </summary>
public class ClassGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曠殑 POCO 绫?
    /// </summary>
    public ClassDeclarationSyntax GeneratePocoClass(
        string className,
        Dictionary<string, string> properties)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞灞炴€?
        foreach (var prop in properties)
        {
            var property = PropertyDeclaration(
                ParseTypeName(prop.Value),
                Identifier(prop.Key))
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
            
            classDecl = classDecl.AddMembers(property);
        }
        
        return classDecl;
    }
    
    /// <summary>
    /// 鐢熸垚甯︽瀯閫犲嚱鏁扮殑绫?
    /// </summary>
    public ClassDeclarationSyntax GenerateClassWithConstructor(
        string className,
        Dictionary<string, string> parameters)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞瀛楁
        foreach (var param in parameters)
        {
            var field = FieldDeclaration(
                VariableDeclaration(ParseTypeName(param.Value))
                .AddVariables(
                    VariableDeclarator(Identifier($"_{param.Key}"))))
            .AddModifiers(
                Token(SyntaxKind.PrivateKeyword),
                Token(SyntaxKind.ReadOnlyKeyword));
            
            classDecl = classDecl.AddMembers(field);
        }
        
        // 鍒涘缓鏋勯€犲嚱鏁?
        var constructor = ConstructorDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddParameterListParameters(
                parameters.Select(p =>
                    Parameter(Identifier(p.Key))
                    .WithType(ParseTypeName(p.Value)))
                .ToArray())
            .WithBody(Block(
                parameters.Select(p =>
                    ExpressionStatement(
                        AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            IdentifierName($"_{p.Key}"),
                            IdentifierName(p.Key))))
                .ToArray()));
        
        classDecl = classDecl.AddMembers(constructor);
        
        return classDecl;
    }
    
    /// <summary>
    /// 鐢熸垚瀹炵幇鎺ュ彛鐨勭被
    /// </summary>
    public ClassDeclarationSyntax GenerateClassWithInterface(
        string className,
        string interfaceName)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddBaseListTypes(
                SimpleBaseType(IdentifierName(interfaceName)));
        
        return classDecl;
    }
}

鐢熸垚娉涘瀷绫?

csharp
/// <summary>
/// 鐢熸垚娉涘瀷绫荤殑绀轰緥
/// </summary>
public class GenericClassGeneration
{
    /// <summary>
    /// 鐢熸垚娉涘瀷绫伙細public class Container<T> { }
    /// </summary>
    public ClassDeclarationSyntax GenerateGenericClass()
    {
        return ClassDeclaration("Container")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("T"));
    }
    
    /// <summary>
    /// 鐢熸垚甯︾害鏉熺殑娉涘瀷绫?
    /// public class Repository<T> where T : class, new() { }
    /// </summary>
    public ClassDeclarationSyntax GenerateGenericClassWithConstraints()
    {
        return ClassDeclaration("Repository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("T"))
            .AddConstraintClauses(
                TypeParameterConstraintClause("T")
                .AddConstraints(
                    ClassOrStructConstraint(SyntaxKind.ClassConstraint),
                    ConstructorConstraint()));
    }
    
    /// <summary>
    /// 鐢熸垚澶氫釜绫诲瀷鍙傛暟鐨勬硾鍨嬬被
    /// public class Pair<TKey, TValue> { }
    /// </summary>
    public ClassDeclarationSyntax GenerateMultipleTypeParametersClass()
    {
        return ClassDeclaration("Pair")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("TKey"),
                TypeParameter("TValue"));
    }
}

鐢熸垚鐗规€э紙Attributes锛?

csharp
/// <summary>
/// 鐢熸垚鐗规€х殑绀轰緥
/// </summary>
public class AttributeGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曠壒鎬э細[Serializable]
    /// </summary>
    public AttributeListSyntax GenerateSimpleAttribute()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("Serializable"))));
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀弬鏁扮殑鐗规€э細[Table("Users")]
    /// </summary>
    public AttributeListSyntax GenerateAttributeWithArgument()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("Table"))
                .AddArgumentListArguments(
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("Users"))))));
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀懡鍚嶅弬鏁扮殑鐗规€э細[JsonProperty(PropertyName = "user_id")]
    /// </summary>
    public AttributeListSyntax GenerateAttributeWithNamedArgument()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("JsonProperty"))
                .AddArgumentListArguments(
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("user_id")))
                    .WithNameEquals(
                        NameEquals(IdentifierName("PropertyName"))))));
    }
}

鐢熸垚鎺ュ彛

csharp
/// <summary>
/// 鐢熸垚鎺ュ彛鐨勭ず渚?
/// </summary>
public class InterfaceGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曟帴鍙?
    /// public interface IRepository { }
    /// </summary>
    public InterfaceDeclarationSyntax GenerateSimpleInterface()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
    }
    
    /// <summary>
    /// 鐢熸垚甯︽柟娉曠殑鎺ュ彛
    /// </summary>
    public InterfaceDeclarationSyntax GenerateInterfaceWithMethods()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                MethodDeclaration(
                    PredefinedType(Token(SyntaxKind.VoidKeyword)),
                    "Save")
                .AddParameterListParameters(
                    Parameter(Identifier("entity"))
                    .WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
    }
    
    /// <summary>
    /// 鐢熸垚娉涘瀷鎺ュ彛
    /// </summary>
    public InterfaceDeclarationSyntax GenerateGenericInterface()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(TypeParameter("T"))
            .AddConstraintClauses(
                TypeParameterConstraintClause("T")
                .AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)));
    }
}

鐢熸垚鏋氫妇

csharp
/// <summary>
/// 鐢熸垚鏋氫妇鐨勭ず渚?
/// </summary>
public class EnumGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曟灇涓?
    /// </summary>
    public EnumDeclarationSyntax GenerateSimpleEnum()
    {
        return EnumDeclaration("Status")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                EnumMemberDeclaration("Active"),
                EnumMemberDeclaration("Inactive"),
                EnumMemberDeclaration("Pending"));
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀€肩殑鏋氫妇
    /// </summary>
    public EnumDeclarationSyntax GenerateEnumWithValues()
    {
        return EnumDeclaration("ErrorCode")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                EnumMemberDeclaration("Success")
                .WithEqualsValue(
                    EqualsValueClause(
                        LiteralExpression(
                            SyntaxKind.NumericLiteralExpression,
                            Literal(0)))),
                EnumMemberDeclaration("NotFound")
                .WithEqualsValue(
                    EqualsValueClause(
                        LiteralExpression(
                            SyntaxKind.NumericLiteralExpression,
                            Literal(404)))));
    }
}

瀛楃涓叉彃鍊?vs SyntaxFactory

浼樼己鐐瑰姣?

瀛楃涓叉彃鍊兼柟寮?

浼樼偣锛?

  • 鉁?绠€鍗曠洿瑙傦紝鏄撲簬鐞嗚В
  • 鉁?蹇€熷師鍨嬪紑鍙?
  • 鉁?閫傚悎绠€鍗曠殑浠g爜鐢熸垚

缂虹偣锛?

  • 鉂?闅句互缁存姢澶嶆潅鐨勪唬鐮佺粨鏋?
  • 鉂?缂哄皯璇硶楠岃瘉
  • 鉂?鏍煎紡鍖栧洶闅?
csharp
// 瀛楃涓叉彃鍊肩ず渚?
public string GenerateClassUsingString(string className)
{
    return $@"
public class {className}
{{
    public string Name {{ get; set; }}
}}";
}

SyntaxFactory 鏂瑰紡

浼樼偣锛?

  • 鉁?绫诲瀷瀹夊叏锛岀紪璇戞椂妫€鏌?
  • 鉁?鏄撲簬缁存姢鍜岄噸鏋?
  • 鉁?鑷姩鏍煎紡鍖?
  • 鉁?鏀寔澶嶆潅鐨勪唬鐮佺粨鏋?

缂虹偣锛?

  • 鉂?瀛︿範鏇茬嚎闄″抄
  • 鉂?浠g爜鍐楅暱

鐪熷疄浣跨敤鍦烘櫙

鍦烘櫙 1: DTO 绫荤敓鎴愬櫒

涓烘暟鎹簱琛ㄨ嚜鍔ㄧ敓鎴?DTO锛圖ata Transfer Object锛夌被銆?

csharp
/// <summary>
/// DTO 绫荤敓鎴愬櫒
/// </summary>
public class DtoGenerator
{
    public class ColumnInfo
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public bool IsNullable { get; set; }
    }
    
    /// <summary>
    /// 鐢熸垚 DTO 绫?
    /// </summary>
    public CompilationUnitSyntax GenerateDto(
        string tableName,
        List<ColumnInfo> columns)
    {
        var className = $"{tableName}Dto";
        
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        foreach (var column in columns)
        {
            var typeName = column.IsNullable ? $"{column.Type}?" : column.Type;
            var property = PropertyDeclaration(
                ParseTypeName(typeName),
                Identifier(column.Name))
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
            
            classDecl = classDecl.AddMembers(property);
        }
        
        var namespaceDecl = NamespaceDeclaration(ParseName("MyApp.Dtos"))
            .AddMembers(classDecl);
        
        return CompilationUnit()
            .AddUsings(UsingDirective(ParseName("System")))
            .AddMembers(namespaceDecl)
            .NormalizeWhitespace();
    }
}

鍦烘櫙 2: Builder 妯″紡鐢熸垚鍣?

涓虹被鑷姩鐢熸垚 Builder 妯″紡浠g爜銆?

csharp
/// <summary>
/// Builder 妯″紡鐢熸垚鍣?
/// </summary>
public class BuilderPatternGenerator
{
    public class PropertyInfo
    {
        public string Name { get; set; }
        public string Type { get; set; }
    }
    
    /// <summary>
    /// 涓虹被鐢熸垚 Builder
    /// </summary>
    public ClassDeclarationSyntax GenerateBuilder(
        string targetClassName,
        List<PropertyInfo> properties)
    {
        var builderClassName = $"{targetClassName}Builder";
        
        var builderClass = ClassDeclaration(builderClassName)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞绉佹湁瀛楁
        foreach (var prop in properties)
        {
            var field = FieldDeclaration(
                VariableDeclaration(ParseTypeName(prop.Type))
                .AddVariables(
                    VariableDeclarator(Identifier($"_{ToCamelCase(prop.Name)}"))))
            .AddModifiers(Token(SyntaxKind.PrivateKeyword));
            
            builderClass = builderClass.AddMembers(field);
        }
        
        // 娣诲姞 With 鏂规硶
        foreach (var prop in properties)
        {
            var withMethod = GenerateWithMethod(builderClassName, prop);
            builderClass = builderClass.AddMembers(withMethod);
        }
        
        return builderClass;
    }
    
    private MethodDeclarationSyntax GenerateWithMethod(
        string builderClassName,
        PropertyInfo property)
    {
        var fieldName = $"_{ToCamelCase(property.Name)}";
        var paramName = ToCamelCase(property.Name);
        
        return MethodDeclaration(
            IdentifierName(builderClassName),
            $"With{property.Name}")
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddParameterListParameters(
            Parameter(Identifier(paramName))
            .WithType(ParseTypeName(property.Type)))
        .WithBody(Block(
            ExpressionStatement(
                AssignmentExpression(
                    SyntaxKind.SimpleAssignmentExpression,
                    IdentifierName(fieldName),
                    IdentifierName(paramName))),
            ReturnStatement(ThisExpression())));
    }
    
    private string ToCamelCase(string name)
    {
        if (string.IsNullOrEmpty(name)) return name;
        return char.ToLower(name[0]) + name.Substring(1);
    }
}

甯歌闂瑙g瓟锛團AQ锛?

Q1: 濡備綍鐢熸垚甯﹀懡鍚嶇┖闂寸殑瀹屾暣浠g爜鏂囦欢锛?

**绛?*: 浣跨敤 CompilationUnit 鍜?NamespaceDeclaration锛?

csharp
var compilationUnit = CompilationUnit()
    .AddUsings(UsingDirective(ParseName("System")))
    .AddMembers(
        NamespaceDeclaration(ParseName("MyNamespace"))
        .AddMembers(classDeclaration))
    .NormalizeWhitespace();

Q2: 濡備綍涓虹敓鎴愮殑浠g爜娣诲姞 XML 鏂囨。娉ㄩ噴锛?

**绛?*: 浣跨敤 WithLeadingTrivia 娣诲姞娉ㄩ噴锛?

csharp
var classDecl = ClassDeclaration("MyClass")
    .WithLeadingTrivia(
        TriviaList(
            Comment("/// <summary>"),
            CarriageReturnLineFeed,
            Comment("/// 鎴戠殑绫?),
            CarriageReturnLineFeed,
            Comment("/// </summary>"),
            CarriageReturnLineFeed));

Q3: 濡備綍鐢熸垚 async/await 浠g爜锛?

**绛?*: 浣跨敤 AsyncKeyword 淇グ绗﹀拰 AwaitExpression锛?

csharp
var method = MethodDeclaration(
    GenericName("Task")
    .AddTypeArgumentListArguments(
        PredefinedType(Token(SyntaxKind.IntKeyword))),
    "GetValueAsync")
.AddModifiers(
    Token(SyntaxKind.PublicKeyword),
    Token(SyntaxKind.AsyncKeyword))
.WithBody(Block(
    ReturnStatement(
        AwaitExpression(
            InvocationExpression(
                IdentifierName("SomeAsyncMethod"))))));

Q4: 濡備綍鐢熸垚 Lambda 琛ㄨ揪寮忥紵

**绛?*: 浣跨敤 SimpleLambdaExpression锛?

csharp
// 鐢熸垚锛歺 => x * 2
var lambda = SimpleLambdaExpression(
    Parameter(Identifier("x")),
    BinaryExpression(
        SyntaxKind.MultiplyExpression,
        IdentifierName("x"),
        LiteralExpression(
            SyntaxKind.NumericLiteralExpression,
            Literal(2))));

Q5: 濡備綍鐢熸垚 record 绫诲瀷锛圕# 9.0+锛夛紵

**绛?*: 浣跨敤 RecordDeclaration锛?

csharp
// 鐢熸垚锛歱ublic record Person(string Name, int Age);
var record = RecordDeclaration(
    Token(SyntaxKind.RecordKeyword),
    "Person")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.WithParameterList(
    ParameterList(
        SeparatedList(new[]
        {
            Parameter(Identifier("Name"))
            .WithType(PredefinedType(Token(SyntaxKind.StringKeyword))),
            Parameter(Identifier("Age"))
            .WithType(PredefinedType(Token(SyntaxKind.IntKeyword)))
        })))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

馃挕 鏈€浣冲疄璺?

瀹炶返 1: 浣跨敤杈呭姪鏂规硶灏佽甯歌妯″紡

csharp
// 鉁?濂斤細灏佽甯歌妯″紡
public static PropertyDeclarationSyntax CreateAutoProperty(
    string typeName,
    string propertyName)
{
    return PropertyDeclaration(
        ParseTypeName(typeName),
        Identifier(propertyName))
    .AddModifiers(Token(SyntaxKind.PublicKeyword))
    .AddAccessorListAccessors(
        AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
            .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
        AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
            .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}

瀹炶返 2: 浣跨敤鏋勫缓鍣ㄦā寮忕粍缁囧鏉備唬鐮?

csharp
// 鉁?濂斤細浣跨敤鏋勫缓鍣ㄦā寮?
var classDecl = new ClassBuilder()
    .WithName("Person")
    .WithModifier("public")
    .AddProperty("string", "Name")
    .AddProperty("int", "Age")
    .Build();

瀹炶返 3: 濮嬬粓鏍煎紡鍖栫敓鎴愮殑浠g爜

csharp
// 鉁?濂斤細鏍煎紡鍖栦唬鐮?
var code = classDecl.NormalizeWhitespace().ToFullString();

鈿狅笍 甯歌閿欒

閿欒 1: 蹇樿娣诲姞绫诲瀷绾︽潫

闂: 娉涘瀷绫荤己灏戝繀瑕佺殑绾︽潫銆?

csharp
// 鉂?閿欒锛氱己灏戠害鏉?
var genericClass = ClassDeclaration("Repository")
    .AddTypeParameterListParameters(TypeParameter("T"));

瑙e喅鏂规: 娣诲姞绫诲瀷绾︽潫銆?

csharp
// 鉁?姝g‘锛氭坊鍔犵害鏉?
var genericClass = ClassDeclaration("Repository")
    .AddTypeParameterListParameters(TypeParameter("T"))
    .AddConstraintClauses(
        TypeParameterConstraintClause("T")
        .AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)));

閿欒 2: 鐗规€у弬鏁伴敊璇?

闂: 鐗规€у弬鏁扮被鍨嬫垨鏍煎紡閿欒銆?

csharp
// 鉂?閿欒锛氬弬鏁扮被鍨嬮敊璇?
var attribute = Attribute(IdentifierName("Table"))
    .AddArgumentListArguments(
        AttributeArgument(IdentifierName("Users")));  // 搴旇鏄瓧绗︿覆瀛楅潰閲?

瑙e喅鏂规: 浣跨敤姝g‘鐨勫弬鏁扮被鍨嬨€?

csharp
// 鉁?姝g‘锛氫娇鐢ㄥ瓧绗︿覆瀛楅潰閲?
var attribute = Attribute(IdentifierName("Table"))
    .AddArgumentListArguments(
        AttributeArgument(
            LiteralExpression(
                SyntaxKind.StringLiteralExpression,
                Literal("Users"))));

馃敆 鐩稿叧鏂囨。

鍏朵粬鐩稿叧鏂囨。


馃摎 涓嬩竴姝?

瀛︿範瀹屾湰鏂囨。鍚庯紝寤鸿缁х画瀛︿範锛?

  1. 浠g爜鏋勫缓妯″紡 - 瀛︿範濡備綍缁勭粐澶嶆潅鐨勪唬鐮佺敓鎴愰€昏緫
  2. [鏈€浣冲疄璺礭(./best-practices.md) - 鎺屾彙浠g爜鐢熸垚鐨勬渶浣冲疄璺靛拰鎬ц兘浼樺寲
  3. 瀹炴垬绀轰緥 - 鏌ョ湅瀹屾暣鐨勬簮鐢熸垚鍣ㄧず渚?

**鏈€鍚庢洿鏂?*: 2026-02-05
鏂囨。鐗堟湰: 1.0

澶嶆潅缁撴瀯鐢熸垚

鐢熸垚绫?

csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勭被
/// </summary>
public class ClassGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曠殑 POCO 绫?
    /// </summary>
    public ClassDeclarationSyntax GeneratePocoClass(
        string className,
        Dictionary<string, string> properties)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞灞炴€?
        foreach (var prop in properties)
        {
            var property = PropertyDeclaration(
                ParseTypeName(prop.Value),
                Identifier(prop.Key))
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
            
            classDecl = classDecl.AddMembers(property);
        }
        
        return classDecl;
    }
    
    /// <summary>
    /// 鐢熸垚甯︽瀯閫犲嚱鏁扮殑绫?
    /// </summary>
    public ClassDeclarationSyntax GenerateClassWithConstructor(
        string className,
        Dictionary<string, string> parameters)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞瀛楁
        foreach (var param in parameters)
        {
            var field = FieldDeclaration(
                VariableDeclaration(ParseTypeName(param.Value))
                .AddVariables(
                    VariableDeclarator(Identifier($"_{param.Key}"))))
            .AddModifiers(
                Token(SyntaxKind.PrivateKeyword),
                Token(SyntaxKind.ReadOnlyKeyword));
            
            classDecl = classDecl.AddMembers(field);
        }
        
        // 鍒涘缓鏋勯€犲嚱鏁?
        var constructor = ConstructorDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddParameterListParameters(
                parameters.Select(p =>
                    Parameter(Identifier(p.Key))
                    .WithType(ParseTypeName(p.Value)))
                .ToArray())
            .WithBody(Block(
                parameters.Select(p =>
                    ExpressionStatement(
                        AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            IdentifierName($"_{p.Key}"),
                            IdentifierName(p.Key))))
                .ToArray()));
        
        classDecl = classDecl.AddMembers(constructor);
        
        return classDecl;
    }
    
    /// <summary>
    /// 鐢熸垚瀹炵幇鎺ュ彛鐨勭被
    /// </summary>
    public ClassDeclarationSyntax GenerateClassWithInterface(
        string className,
        string interfaceName)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddBaseListTypes(
                SimpleBaseType(IdentifierName(interfaceName)));
        
        return classDecl;
    }
    
    /// <summary>
    /// 鐢熸垚缁ф壙鍩虹被鐨勭被
    /// </summary>
    public ClassDeclarationSyntax GenerateClassWithBaseClass(
        string className,
        string baseClassName)
    {
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddBaseListTypes(
                SimpleBaseType(IdentifierName(baseClassName)));
        
        return classDecl;
    }
}

鐢熸垚鏂规硶

csharp
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勬柟娉?
/// </summary>
public class MethodGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曠殑鏂规硶
    /// </summary>
    public MethodDeclarationSyntax GenerateSimpleMethod()
    {
        // 鐢熸垚锛歱ublic void DoSomething() { }
        return MethodDeclaration(
            PredefinedType(Token(SyntaxKind.VoidKeyword)),
            Identifier("DoSomething"))
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .WithBody(Block());
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀弬鏁扮殑鏂规硶
    /// </summary>
    public MethodDeclarationSyntax GenerateMethodWithParameters()
    {
        // 鐢熸垚锛歱ublic int Add(int a, int b) { return a + b; }
        return MethodDeclaration(
            PredefinedType(Token(SyntaxKind.IntKeyword)),
            Identifier("Add"))
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddParameterListParameters(
            Parameter(Identifier("a"))
                .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))),
            Parameter(Identifier("b"))
                .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
        .WithBody(Block(
            ReturnStatement(
                BinaryExpression(
                    SyntaxKind.AddExpression,
                    IdentifierName("a"),
                    IdentifierName("b")))));
    }
}

鐢熸垚灞炴€?

csharp
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勫睘鎬?
/// </summary>
public class PropertyGeneration
{
    /// <summary>
    /// 鐢熸垚鑷姩灞炴€?
    /// </summary>
    public PropertyDeclarationSyntax GenerateAutoProperty(
        string typeName,
        string propertyName)
    {
        // 鐢熸垚锛歱ublic string Name { get; set; }
        return PropertyDeclaration(
            ParseTypeName(typeName),
            Identifier(propertyName))
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddAccessorListAccessors(
            AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
            AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
    }
    
    /// <summary>
    /// 鐢熸垚鍙灞炴€?
    /// </summary>
    public PropertyDeclarationSyntax GenerateReadOnlyProperty(
        string typeName,
        string propertyName)
    {
        // 鐢熸垚锛歱ublic string Name { get; }
        return PropertyDeclaration(
            ParseTypeName(typeName),
            Identifier(propertyName))
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddAccessorListAccessors(
            AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
    }
}

鐢熸垚娉涘瀷绫?

csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// 鐢熸垚娉涘瀷绫荤殑绀轰緥
/// </summary>
public class GenericClassGeneration
{
    /// <summary>
    /// 鐢熸垚娉涘瀷绫伙細public class Container<T> { }
    /// </summary>
    public ClassDeclarationSyntax GenerateGenericClass()
    {
        return ClassDeclaration("Container")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("T"));
    }
    
    /// <summary>
    /// 鐢熸垚甯︾害鏉熺殑娉涘瀷绫?
    /// public class Repository<T> where T : class, new() { }
    /// </summary>
    public ClassDeclarationSyntax GenerateGenericClassWithConstraints()
    {
        return ClassDeclaration("Repository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("T"))
            .AddConstraintClauses(
                TypeParameterConstraintClause("T")
                .AddConstraints(
                    ClassOrStructConstraint(SyntaxKind.ClassConstraint),
                    ConstructorConstraint()));
    }
    
    /// <summary>
    /// 鐢熸垚澶氫釜绫诲瀷鍙傛暟鐨勬硾鍨嬬被
    /// public class Pair<TKey, TValue> { }
    /// </summary>
    public ClassDeclarationSyntax GenerateMultipleTypeParametersClass()
    {
        return ClassDeclaration("Pair")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(
                TypeParameter("TKey"),
                TypeParameter("TValue"));
    }
}

鐢熸垚鐗规€э紙Attributes锛?

csharp
/// <summary>
/// 鐢熸垚鐗规€х殑绀轰緥
/// </summary>
public class AttributeGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曠壒鎬э細[Serializable]
    /// </summary>
    public AttributeListSyntax GenerateSimpleAttribute()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("Serializable"))));
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀弬鏁扮殑鐗规€э細[Table("Users")]
    /// </summary>
    public AttributeListSyntax GenerateAttributeWithArgument()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("Table"))
                .AddArgumentListArguments(
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("Users"))))));
    }
    
    /// <summary>
    /// 鐢熸垚甯﹀懡鍚嶅弬鏁扮殑鐗规€э細[JsonProperty(PropertyName = "user_id")]
    /// </summary>
    public AttributeListSyntax GenerateAttributeWithNamedArgument()
    {
        return AttributeList(
            SingletonSeparatedList(
                Attribute(IdentifierName("JsonProperty"))
                .AddArgumentListArguments(
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("user_id")))
                    .WithNameEquals(
                        NameEquals(IdentifierName("PropertyName"))))));
    }
    
    /// <summary>
    /// 涓虹被娣诲姞澶氫釜鐗规€?
    /// </summary>
    public ClassDeclarationSyntax AddAttributesToClass(
        ClassDeclarationSyntax classDecl,
        params AttributeListSyntax[] attributes)
    {
        return classDecl.AddAttributeLists(attributes);
    }
}

鐢熸垚鎺ュ彛

csharp
/// <summary>
/// 鐢熸垚鎺ュ彛鐨勭ず渚?
/// </summary>
public class InterfaceGeneration
{
    /// <summary>
    /// 鐢熸垚绠€鍗曟帴鍙?
    /// public interface IRepository { }
    /// </summary>
    public InterfaceDeclarationSyntax GenerateSimpleInterface()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
    }
    
    /// <summary>
    /// 鐢熸垚甯︽柟娉曠殑鎺ュ彛
    /// public interface IRepository
    /// {
    ///     void Save(object entity);
    ///     object Load(int id);
    /// }
    /// </summary>
    public InterfaceDeclarationSyntax GenerateInterfaceWithMethods()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                // void Save(object entity);
                MethodDeclaration(
                    PredefinedType(Token(SyntaxKind.VoidKeyword)),
                    "Save")
                .AddParameterListParameters(
                    Parameter(Identifier("entity"))
                    .WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                
                // object Load(int id);
                MethodDeclaration(
                    PredefinedType(Token(SyntaxKind.ObjectKeyword)),
                    "Load")
                .AddParameterListParameters(
                    Parameter(Identifier("id"))
                    .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
    }
    
    /// <summary>
    /// 鐢熸垚娉涘瀷鎺ュ彛
    /// public interface IRepository<T> where T : class
    /// {
    ///     void Save(T entity);
    ///     T Load(int id);
    /// }
    /// </summary>
    public InterfaceDeclarationSyntax GenerateGenericInterface()
    {
        return InterfaceDeclaration("IRepository")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddTypeParameterListParameters(TypeParameter("T"))
            .AddConstraintClauses(
                TypeParameterConstraintClause("T")
                .AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)))
            .AddMembers(
                MethodDeclaration(
                    PredefinedType(Token(SyntaxKind.VoidKeyword)),
                    "Save")
                .AddParameterListParameters(
                    Parameter(Identifier("entity"))
                    .WithType(IdentifierName("T")))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                
                MethodDeclaration(
                    IdentifierName("T"),
                    "Load")
                .AddParameterListParameters(
                    Parameter(Identifier("id"))
                    .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
    }
}

---

##  下一步

继续阅读 [Part 2](./syntax-factory-advanced-part2.md)

---

*最后更新: 2025-01-21*

基于 MIT 许可发布