Skip to content

SyntaxFactory 高级用法 - Part 2

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

文档信息

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

---

## 鐢熸垚鏋氫妇

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

鐪熷疄浣跨敤鍦烘櫙

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

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

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

/// <summary>
/// 鍦烘櫙锛欴TO 绫荤敓鎴愬櫒
/// 鏍规嵁鏁版嵁搴撹〃缁撴瀯鑷姩鐢熸垚 DTO 绫?
/// </summary>
public class DtoGenerator
{
    /// <summary>
    /// 琛ㄥ垪淇℃伅
    /// </summary>
    public class ColumnInfo
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public bool IsNullable { get; set; }
        public string Description { get; set; }
    }
    
    /// <summary>
    /// 鐢熸垚 DTO 绫?
    /// </summary>
    public CompilationUnitSyntax GenerateDto(
        string tableName,
        List<ColumnInfo> columns)
    {
        // 绫诲悕锛歎serDto
        var className = $"{tableName}Dto";
        
        // 鍒涘缓绫?
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞 XML 鏂囨。娉ㄩ噴
        classDecl = classDecl.WithLeadingTrivia(
            TriviaList(
                Comment("/// <summary>"),
                CarriageReturnLineFeed,
                Comment($"/// {tableName} 琛ㄧ殑 DTO 绫?),
                CarriageReturnLineFeed,
                Comment("/// </summary>"),
                CarriageReturnLineFeed));
        
        // 涓烘瘡涓垪鐢熸垚灞炴€?
        foreach (var column in columns)
        {
            var property = GenerateProperty(column);
            classDecl = classDecl.AddMembers(property);
        }
        
        // 鍒涘缓鍛藉悕绌洪棿
        var namespaceDecl = NamespaceDeclaration(ParseName("MyApp.Dtos"))
            .AddMembers(classDecl);
        
        // 鍒涘缓缂栬瘧鍗曞厓
        return CompilationUnit()
            .AddUsings(UsingDirective(ParseName("System")))
            .AddMembers(namespaceDecl)
            .NormalizeWhitespace();
    }
    
    /// <summary>
    /// 鐢熸垚灞炴€?
    /// </summary>
    private PropertyDeclarationSyntax GenerateProperty(ColumnInfo column)
    {
        // 纭畾灞炴€х被鍨?
        var typeName = column.Type;
        if (column.IsNullable && IsValueType(column.Type))
        {
            typeName = $"{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)));
        
        // 娣诲姞 XML 鏂囨。娉ㄩ噴
        if (!string.IsNullOrEmpty(column.Description))
        {
            property = property.WithLeadingTrivia(
                TriviaList(
                    CarriageReturnLineFeed,
                    Whitespace("    "),
                    Comment("/// <summary>"),
                    CarriageReturnLineFeed,
                    Whitespace("    "),
                    Comment($"/// {column.Description}"),
                    CarriageReturnLineFeed,
                    Whitespace("    "),
                    Comment("/// </summary>"),
                    CarriageReturnLineFeed,
                    Whitespace("    ")));
        }
        
        return property;
    }
    
    /// <summary>
    /// 鍒ゆ柇鏄惁涓哄€肩被鍨?
    /// </summary>
    private bool IsValueType(string typeName)
    {
        return typeName switch
        {
            "int" or "long" or "short" or "byte" or
            "decimal" or "double" or "float" or
            "bool" or "DateTime" or "Guid" => true,
            _ => false
        };
    }
}

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

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

csharp
/// <summary>
/// 鍦烘櫙锛欱uilder 妯″紡鐢熸垚鍣?
/// 涓虹幇鏈夌被鐢熸垚娴佸紡 Builder 绫?
/// </summary>
public class BuilderPatternGenerator
{
    /// <summary>
    /// 涓虹被鐢熸垚 Builder
    /// </summary>
    public ClassDeclarationSyntax GenerateBuilder(
        string targetClassName,
        List<PropertyInfo> properties)
    {
        var builderClassName = $"{targetClassName}Builder";
        
        // 鍒涘缓 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);
        }
        
        // 娣诲姞 Build 鏂规硶
        var buildMethod = GenerateBuildMethod(targetClassName, properties);
        builderClass = builderClass.AddMembers(buildMethod);
        
        return builderClass;
    }
    
    /// <summary>
    /// 鐢熸垚 With 鏂规硶
    /// public PersonBuilder WithName(string name)
    /// {
    ///     _name = name;
    ///     return this;
    /// }
    /// </summary>
    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(
            // _name = name;
            ExpressionStatement(
                AssignmentExpression(
                    SyntaxKind.SimpleAssignmentExpression,
                    IdentifierName(fieldName),
                    IdentifierName(paramName))),
            // return this;
            ReturnStatement(ThisExpression())));
    }
    
    /// <summary>
    /// 鐢熸垚 Build 鏂规硶
    /// public Person Build()
    /// {
    ///     return new Person
    ///     {
    ///         Name = _name,
    ///         Age = _age
    ///     };
    /// }
    /// </summary>
    private MethodDeclarationSyntax GenerateBuildMethod(
        string targetClassName,
        List<PropertyInfo> properties)
    {
        // 鍒涘缓瀵硅薄鍒濆鍖栧櫒
        var initializers = properties.Select(prop =>
            AssignmentExpression(
                SyntaxKind.SimpleAssignmentExpression,
                IdentifierName(prop.Name),
                IdentifierName($"_{ToCamelCase(prop.Name)}")));
        
        return MethodDeclaration(
            IdentifierName(targetClassName),
            "Build")
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .WithBody(Block(
            ReturnStatement(
                ObjectCreationExpression(IdentifierName(targetClassName))
                .WithInitializer(
                    InitializerExpression(
                        SyntaxKind.ObjectInitializerExpression,
                        SeparatedList<ExpressionSyntax>(initializers))))));
    }
    
    private string ToCamelCase(string name)
    {
        if (string.IsNullOrEmpty(name)) return name;
        return char.ToLower(name[0]) + name.Substring(1);
    }
    
    public class PropertyInfo
    {
        public string Name { get; set; }
        public string Type { get; set; }
    }
}

鍦烘櫙 3: API 瀹㈡埛绔敓鎴愬櫒

鏍规嵁 API 瀹氫箟鑷姩鐢熸垚瀹㈡埛绔唬鐮併€?

csharp
/// <summary>
/// 鍦烘櫙锛欰PI 瀹㈡埛绔敓鎴愬櫒
/// 鏍规嵁 API 瀹氫箟鐢熸垚 HTTP 瀹㈡埛绔唬鐮?
/// </summary>
public class ApiClientGenerator
{
    public class ApiEndpoint
    {
        public string Name { get; set; }
        public string Method { get; set; } // GET, POST, PUT, DELETE
        public string Path { get; set; }
        public List<Parameter> Parameters { get; set; }
        public string ReturnType { get; set; }
    }
    
    public class Parameter
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public bool IsRequired { get; set; }
    }
    
    /// <summary>
    /// 鐢熸垚 API 瀹㈡埛绔被
    /// </summary>
    public CompilationUnitSyntax GenerateApiClient(
        string clientName,
        List<ApiEndpoint> endpoints)
    {
        // 鍒涘缓瀹㈡埛绔被
        var clientClass = ClassDeclaration(clientName)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 娣诲姞 HttpClient 瀛楁
        var httpClientField = FieldDeclaration(
            VariableDeclaration(IdentifierName("HttpClient"))
            .AddVariables(VariableDeclarator("_httpClient")))
        .AddModifiers(
            Token(SyntaxKind.PrivateKeyword),
            Token(SyntaxKind.ReadOnlyKeyword));
        
        clientClass = clientClass.AddMembers(httpClientField);
        
        // 娣诲姞鏋勯€犲嚱鏁?
        var constructor = ConstructorDeclaration(clientName)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddParameterListParameters(
                Parameter(Identifier("httpClient"))
                .WithType(IdentifierName("HttpClient")))
            .WithBody(Block(
                ExpressionStatement(
                    AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        IdentifierName("_httpClient"),
                        IdentifierName("httpClient")))));
        
        clientClass = clientClass.AddMembers(constructor);
        
        // 涓烘瘡涓鐐圭敓鎴愭柟娉?
        foreach (var endpoint in endpoints)
        {
            var method = GenerateEndpointMethod(endpoint);
            clientClass = clientClass.AddMembers(method);
        }
        
        // 鍒涘缓鍛藉悕绌洪棿
        var namespaceDecl = NamespaceDeclaration(ParseName("MyApp.ApiClients"))
            .AddMembers(clientClass);
        
        // 鍒涘缓缂栬瘧鍗曞厓
        return CompilationUnit()
            .AddUsings(
                UsingDirective(ParseName("System")),
                UsingDirective(ParseName("System.Net.Http")),
                UsingDirective(ParseName("System.Threading.Tasks")))
            .AddMembers(namespaceDecl)
            .NormalizeWhitespace();
    }
    
    /// <summary>
    /// 鐢熸垚绔偣鏂规硶
    /// public async Task<User> GetUserAsync(int id)
    /// {
    ///     var response = await _httpClient.GetAsync($"/api/users/{id}");
    ///     response.EnsureSuccessStatusCode();
    ///     return await response.Content.ReadAsAsync<User>();
    /// }
    /// </summary>
    private MethodDeclarationSyntax GenerateEndpointMethod(ApiEndpoint endpoint)
    {
        // 鏂规硶鍚?
        var methodName = $"{endpoint.Name}Async";
        
        // 杩斿洖绫诲瀷锛歍ask<ReturnType>
        var returnType = GenericName("Task")
            .AddTypeArgumentListArguments(
                IdentifierName(endpoint.ReturnType));
        
        // 鍒涘缓鏂规硶
        var method = MethodDeclaration(returnType, methodName)
            .AddModifiers(
                Token(SyntaxKind.PublicKeyword),
                Token(SyntaxKind.AsyncKeyword));
        
        // 娣诲姞鍙傛暟
        foreach (var param in endpoint.Parameters)
        {
            method = method.AddParameterListParameters(
                Parameter(Identifier(param.Name))
                .WithType(ParseTypeName(param.Type)));
        }
        
        // 鐢熸垚鏂规硶浣擄紙绠€鍖栫増锛?
        var methodBody = GenerateMethodBody(endpoint);
        method = method.WithBody(Block(methodBody));
        
        return method;
    }
    
    private StatementSyntax[] GenerateMethodBody(ApiEndpoint endpoint)
    {
        // 绠€鍖栫殑鏂规硶浣撶敓鎴?
        // 瀹為檯搴旇鏍规嵁 HTTP 鏂规硶鐢熸垚涓嶅悓鐨勪唬鐮?
        return new[]
        {
            // var response = await _httpClient.GetAsync(...);
            LocalDeclarationStatement(
                VariableDeclaration(IdentifierName("var"))
                .AddVariables(
                    VariableDeclarator("response")
                    .WithInitializer(
                        EqualsValueClause(
                            AwaitExpression(
                                InvocationExpression(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName("_httpClient"),
                                        IdentifierName($"{endpoint.Method}Async")))))))),
            
            // return default;
            ReturnStatement(
                LiteralExpression(SyntaxKind.DefaultLiteralExpression))
        };
    }
}

瀛楃涓叉彃鍊?vs SyntaxFactory

浼樼己鐐瑰姣?

瀛楃涓叉彃鍊兼柟寮?

浼樼偣锛?

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

缂虹偣锛?

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

SyntaxFactory 鏂瑰紡

浼樼偣锛?

  • 鉁?绫诲瀷瀹夊叏锛岀紪璇戞椂妫€鏌?
  • 鉁?鏄撲簬缁存姢鍜岄噸鏋?
  • 鉁?鑷姩鏍煎紡鍖?
  • 鉁?鏀寔澶嶆潅鐨勪唬鐮佺粨鏋?
  • 鉁?鍙互鍒╃敤 Roslyn 鐨勮娉曞垎鏋?

缂虹偣锛?

  • 鉂?瀛︿範鏇茬嚎闄″抄
  • 鉂?浠g爜鍐楅暱
  • 鉂?鍒濇湡寮€鍙戦€熷害杈冩參
csharp
// SyntaxFactory 绀轰緥
public ClassDeclarationSyntax GenerateClassUsingSyntaxFactory(
    string className)
{
    return ClassDeclaration(className)
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddMembers(
            PropertyDeclaration(
                PredefinedType(Token(SyntaxKind.StringKeyword)),
                "Name")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddAccessorListAccessors(
                AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))));
}

浣跨敤鍦烘櫙寤鸿

浣跨敤瀛楃涓叉彃鍊肩殑鍦烘櫙

  • 绠€鍗曠殑浠g爜鐗囨鐢熸垚
  • 蹇€熷師鍨嬪紑鍙?
  • 涓€娆℃€х殑浠g爜鐢熸垚浠诲姟
  • 妯℃澘闈炲父绠€鍗曚笖涓嶄細鏀瑰彉
csharp
// 鉁?閫傚悎瀛楃涓叉彃鍊硷細绠€鍗曠殑灞炴€х敓鎴?
public string GenerateSimpleProperty(string name, string type)
{
    return $"public {type} {name} {{ get; set; }}";
}

浣跨敤 SyntaxFactory 鐨勫満鏅?

  • 澶嶆潅鐨勪唬鐮佺粨鏋?
  • 闇€瑕佺淮鎶ょ殑鐢熸垚鍣?
  • 闇€瑕佽娉曢獙璇?
  • 闇€瑕佷笌鐜版湁浠g爜闆嗘垚
csharp
// 鉁?閫傚悎 SyntaxFactory锛氬鏉傜殑绫荤敓鎴?
public ClassDeclarationSyntax GenerateComplexClass(
    string className,
    List<PropertyInfo> properties)
{
    var classDecl = ClassDeclaration(className)
        .AddModifiers(Token(SyntaxKind.PublicKeyword));
    
    foreach (var prop in properties)
    {
        var property = GenerateProperty(prop);
        classDecl = classDecl.AddMembers(property);
    }
    
    return classDecl;
}

娣峰悎浣跨敤绛栫暐

鍦ㄥ疄闄呴」鐩腑锛屽彲浠ョ粨鍚堜袱绉嶆柟寮忕殑浼樼偣锛?

csharp
/// <summary>
/// 娣峰悎浣跨敤瀛楃涓插拰 SyntaxFactory
/// </summary>
public class HybridCodeGeneration
{
    /// <summary>
    /// 浣跨敤瀛楃涓茬敓鎴愮畝鍗曢儴鍒嗭紝SyntaxFactory 鐢熸垚澶嶆潅閮ㄥ垎
    /// </summary>
    public CompilationUnitSyntax GenerateCode(string className)
    {
        // 浣跨敤 SyntaxFactory 鐢熸垚涓昏缁撴瀯
        var classDecl = ClassDeclaration(className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword));
        
        // 瀵逛簬绠€鍗曠殑鏂规硶浣擄紝鍙互浣跨敤 ParseStatement
        var methodBody = ParseStatement(@"
            Console.WriteLine(""Hello, World!"");
            return 42;
        ");
        
        var method = MethodDeclaration(
            PredefinedType(Token(SyntaxKind.IntKeyword)),
            "GetValue")
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .WithBody(Block(methodBody));
        
        classDecl = classDecl.AddMembers(method);
        
        return CompilationUnit()
            .AddMembers(classDecl)
            .NormalizeWhitespace();
    }
}

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

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

A: 浣跨敤 CompilationUnit 鍜?NamespaceDeclaration锛?

csharp
var compilationUnit = CompilationUnit()
    .AddUsings(
        UsingDirective(ParseName("System")))
    .AddMembers(
        NamespaceDeclaration(ParseName("MyNamespace"))
        .AddMembers(
            ClassDeclaration("MyClass")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))))
    .NormalizeWhitespace();

string code = compilationUnit.ToFullString();

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

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

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

Q3: 濡備綍鐢熸垚琛ㄨ揪寮忎富浣撴垚鍛橈紙Expression-bodied members锛夛紵

A: 浣跨敤 WithExpressionBody 鍜?ArrowExpressionClause锛?

csharp
// 鐢熸垚锛歱ublic int GetValue() => 42;
var method = MethodDeclaration(
    PredefinedType(Token(SyntaxKind.IntKeyword)),
    "GetValue")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.WithExpressionBody(
    ArrowExpressionClause(
        LiteralExpression(
            SyntaxKind.NumericLiteralExpression,
            Literal(42))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

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

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

csharp
// 鐢熸垚锛歱ublic async Task<int> GetValueAsync()
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"))))));

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

A: 浣跨敤 SimpleLambdaExpression 鎴?ParenthesizedLambdaExpression锛?

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

// 鐢熸垚锛?x, y) => x + y
var multiParamLambda = ParenthesizedLambdaExpression(
    ParameterList(
        SeparatedList(new[]
        {
            Parameter(Identifier("x")),
            Parameter(Identifier("y"))
        })),
    BinaryExpression(
        SyntaxKind.AddExpression,
        IdentifierName("x"),
        IdentifierName("y")));

Q6: 濡備綍鐢熸垚 LINQ 鏌ヨ琛ㄨ揪寮忥紵

A: 浣跨敤 QueryExpression 鍜岀浉鍏崇殑鏌ヨ瀛愬彞锛?

csharp
// 鐢熸垚锛歠rom x in numbers where x > 5 select x * 2
var query = QueryExpression(
    QueryBody(
        SingletonList<QueryClauseSyntax>(
            WhereClause(
                BinaryExpression(
                    SyntaxKind.GreaterThanExpression,
                    IdentifierName("x"),
                    LiteralExpression(
                        SyntaxKind.NumericLiteralExpression,
                        Literal(5))))),
        SelectClause(
            BinaryExpression(
                SyntaxKind.MultiplyExpression,
                IdentifierName("x"),
                LiteralExpression(
                    SyntaxKind.NumericLiteralExpression,
                    Literal(2)))),
        null))
.WithFromClause(
    FromClause(
        Identifier("x"),
        IdentifierName("numbers")));

Q7: 濡備綍鐢熸垚 switch 琛ㄨ揪寮忥紙C# 8.0+锛夛紵

A: 浣跨敤 SwitchExpression锛?

csharp
// 鐢熸垚锛歷alue switch { 1 => "one", 2 => "two", _ => "other" }
var switchExpr = SwitchExpression(
    IdentifierName("value"),
    SeparatedList(new[]
    {
        SwitchExpressionArm(
            ConstantPattern(
                LiteralExpression(
                    SyntaxKind.NumericLiteralExpression,
                    Literal(1))),
            LiteralExpression(
                SyntaxKind.StringLiteralExpression,
                Literal("one"))),
        SwitchExpressionArm(
            ConstantPattern(
                LiteralExpression(
                    SyntaxKind.NumericLiteralExpression,
                    Literal(2))),
            LiteralExpression(
                SyntaxKind.StringLiteralExpression,
                Literal("two"))),
        SwitchExpressionArm(
            DiscardPattern(),
            LiteralExpression(
                SyntaxKind.StringLiteralExpression,
                Literal("other")))
    }));

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

A: 浣跨敤 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));

Q9: 濡備綍鐢熸垚 using 澹版槑锛圕# 8.0+锛夛紵

A: 浣跨敤 LocalDeclarationStatement 鍜?UsingKeyword锛?

csharp
// 鐢熸垚锛歶sing var stream = File.OpenRead("file.txt");
var usingDecl = LocalDeclarationStatement(
    VariableDeclaration(IdentifierName("var"))
    .AddVariables(
        VariableDeclarator("stream")
        .WithInitializer(
            EqualsValueClause(
                InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        IdentifierName("File"),
                        IdentifierName("OpenRead")))
                .AddArgumentListArguments(
                    Argument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("file.txt"))))))))
.AddModifiers(Token(SyntaxKind.UsingKeyword));

Q10: 濡備綍鐢熸垚 nullable 寮曠敤绫诲瀷娉ㄨВ锛?

A: 浣跨敤 NullableType锛?

csharp
// 鐢熸垚锛歴tring? name
var nullableType = NullableType(
    PredefinedType(Token(SyntaxKind.StringKeyword)));

// 鍦ㄥ睘鎬т腑浣跨敤
var property = PropertyDeclaration(
    nullableType,
    "Name")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
    AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

Q11: 濡備綍鐢熸垚 init 璁块棶鍣紙C# 9.0+锛夛紵

A: 浣跨敤 InitAccessorDeclaration锛?

csharp
// 鐢熸垚锛歱ublic string Name { get; init; }
var property = PropertyDeclaration(
    PredefinedType(Token(SyntaxKind.StringKeyword)),
    "Name")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
    AccessorDeclaration(SyntaxKind.InitAccessorDeclaration)
        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

Q12: 濡備綍鐢熸垚 pattern matching锛?

A: 浣跨敤鍚勭 Pattern 绫诲瀷锛?

csharp
// 鐢熸垚锛歩f (obj is string s) { }
var isPattern = IsPatternExpression(
    IdentifierName("obj"),
    DeclarationPattern(
        PredefinedType(Token(SyntaxKind.StringKeyword)),
        SingleVariableDesignation(Identifier("s"))));

var ifStatement = IfStatement(
    isPattern,
    Block());

Q13: 濡備綍鐢熸垚 tuple 绫诲瀷锛?

A: 浣跨敤 TupleType锛?

csharp
// 鐢熸垚锛?int, string)
var tupleType = TupleType(
    SeparatedList(new[]
    {
        TupleElement(PredefinedType(Token(SyntaxKind.IntKeyword))),
        TupleElement(PredefinedType(Token(SyntaxKind.StringKeyword)))
    }));

// 鐢熸垚甯﹀悕绉扮殑 tuple锛?int id, string name)
var namedTupleType = TupleType(
    SeparatedList(new[]
    {
        TupleElement(
            PredefinedType(Token(SyntaxKind.IntKeyword)),
            Identifier("id")),
        TupleElement(
            PredefinedType(Token(SyntaxKind.StringKeyword)),
            Identifier("name"))
    }));

Q14: 濡備綍鐢熸垚 local function锛?

A: 浣跨敤 LocalFunctionStatement锛?

csharp
// 鐢熸垚锛歩nt Add(int a, int b) => a + b;
var localFunction = LocalFunctionStatement(
    PredefinedType(Token(SyntaxKind.IntKeyword)),
    "Add")
.AddParameterListParameters(
    Parameter(Identifier("a"))
    .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))),
    Parameter(Identifier("b"))
    .WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
.WithExpressionBody(
    ArrowExpressionClause(
        BinaryExpression(
            SyntaxKind.AddExpression,
            IdentifierName("a"),
            IdentifierName("b"))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

Q15: 濡備綍澶勭悊鐢熸垚浠g爜涓殑鐗规畩瀛楃鍜岃浆涔夛紵

A: Roslyn 浼氳嚜鍔ㄥ鐞嗚浆涔夛紝浣嗕綘涔熷彲浠ヤ娇鐢?verbatim 瀛楃涓诧細

csharp
// 鏅€氬瓧绗︿覆锛堣嚜鍔ㄨ浆涔夛級
var normalString = LiteralExpression(
    SyntaxKind.StringLiteralExpression,
    Literal("C:\\Path\\To\\File"));

// Verbatim 瀛楃涓?
var verbatimString = LiteralExpression(
    SyntaxKind.StringLiteralExpression,
    Literal(@"C:\Path\To\File", @"C:\Path\To\File"));

馃挕 鏈€浣冲疄璺?

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

csharp
// 鉁?濂界殑鍋氭硶锛氬皝瑁呭父瑙佹ā寮?
public class CodeGenerationHelpers
{
    /// <summary>
    /// 鍒涘缓鍏叡鑷姩灞炴€?
    /// </summary>
    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)));
    }
    
    /// <summary>
    /// 浣跨敤杈呭姪鏂规硶
    /// </summary>
    public ClassDeclarationSyntax GenerateClass()
    {
        return ClassDeclaration("Person")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                CreateAutoProperty("string", "Name"),
                CreateAutoProperty("int", "Age"));
    }
}

鍘熷洜锛氭彁楂樹唬鐮佸鐢ㄦ€у拰鍙淮鎶ゆ€с€?

瀹炶返 2: 浣跨敤鏋勫缓鍣ㄦā寮忕粍缁囧鏉傜敓鎴愰€昏緫

csharp
// 鉁?濂界殑鍋氭硶锛氫娇鐢ㄦ瀯寤哄櫒妯″紡
public class ClassBuilder
{
    private string _className;
    private List<PropertyDeclarationSyntax> _properties = new();
    
    public ClassBuilder WithName(string name)
    {
        _className = name;
        return this;
    }
    
    public ClassBuilder AddProperty(string type, string name)
    {
        var property = PropertyDeclaration(
            ParseTypeName(type),
            Identifier(name))
        .AddModifiers(Token(SyntaxKind.PublicKeyword))
        .AddAccessorListAccessors(
            AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
            AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
        
        _properties.Add(property);
        return this;
    }
    
    public ClassDeclarationSyntax Build()
    {
        return ClassDeclaration(_className)
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(_properties.ToArray());
    }
}

鍘熷洜锛氫娇澶嶆潅鐨勪唬鐮佺敓鎴愰€昏緫鏇存竻鏅般€佹洿鏄撶淮鎶ゃ€?

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

csharp
// 鉁?濂界殑鍋氭硶锛氭牸寮忓寲浠g爜
public string GenerateClass(string className)
{
    var classDecl = ClassDeclaration(className)
        .AddModifiers(Token(SyntaxKind.PublicKeyword));
    
    // 鏍煎紡鍖栦唬鐮?
    var formatted = classDecl.NormalizeWhitespace();
    
    return formatted.ToFullString();
}

鍘熷洜锛氱‘淇濈敓鎴愮殑浠g爜鍏锋湁涓€鑷寸殑鏍煎紡鍜岃壇濂界殑鍙鎬с€?


鈿狅笍 甯歌閿欒

閿欒 1: 蹇樿娣诲姞鍒嗗彿鏍囪

闂: 鏌愪簺璇硶鑺傜偣闇€瑕佹樉寮忔坊鍔犲垎鍙锋爣璁般€?

csharp
// 鉂?閿欒锛氱己灏戝垎鍙锋爣璁?
var accessor = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);
// 缁撴灉锛歡et  // 缂哄皯鍒嗗彿

瑙e喅鏂规:

csharp
// 鉁?姝g‘锛氭坊鍔犲垎鍙锋爣璁?
var accessor = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
// 缁撴灉锛歡et;

閿欒 2: 娉涘瀷绾︽潫椤哄簭閿欒

闂: 娉涘瀷绾︽潫蹇呴』鎸夌壒瀹氶『搴忔坊鍔犮€?

csharp
// 鉂?閿欒锛氱害鏉熼『搴忛敊璇?
var classDecl = ClassDeclaration("MyClass")
    .AddTypeParameterListParameters(TypeParameter("T"))
    .AddConstraintClauses(
        TypeParameterConstraintClause("T")
        .AddConstraints(
            ConstructorConstraint(),  // new() 蹇呴』鍦ㄦ渶鍚?
            ClassOrStructConstraint(SyntaxKind.ClassConstraint)));

瑙e喅鏂规:

csharp
// 鉁?姝g‘锛氱害鏉熼『搴忔纭?
var classDecl = ClassDeclaration("MyClass")
    .AddTypeParameterListParameters(TypeParameter("T"))
    .AddConstraintClauses(
        TypeParameterConstraintClause("T")
        .AddConstraints(
            ClassOrStructConstraint(SyntaxKind.ClassConstraint),
            ConstructorConstraint()));  // new() 鍦ㄦ渶鍚?

閿欒 3: 蹇樿娣诲姞 using 鎸囦护

闂: 鐢熸垚鐨勪唬鐮佷娇鐢ㄤ簡绫诲瀷浣嗘病鏈夋坊鍔犵浉搴旂殑 using 鎸囦护銆?

csharp
// 鉂?閿欒锛氱己灏?using 鎸囦护
var compilationUnit = CompilationUnit()
    .AddMembers(
        NamespaceDeclaration(ParseName("MyNamespace"))
        .AddMembers(classDecl));
// 鐢熸垚鐨勪唬鐮佸彲鑳芥棤娉曠紪璇戯紝鍥犱负缂哄皯蹇呰鐨?using

瑙e喅鏂规:

csharp
// 鉁?姝g‘锛氭坊鍔犲繀瑕佺殑 using 鎸囦护
var compilationUnit = CompilationUnit()
    .AddUsings(
        UsingDirective(ParseName("System")),
        UsingDirective(ParseName("System.Collections.Generic")))
    .AddMembers(
        NamespaceDeclaration(ParseName("MyNamespace"))
        .AddMembers(classDecl));

馃敆 鐩稿叧鏂囨。

鍏朵粬鐩稿叧鏂囨。


馃摎 涓嬩竴姝?

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

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

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


📝 相关文档


最后更新: 2025-01-21

基于 MIT 许可发布