Skip to content
    ["Content-Type"] = "application/json"
},
AuthToken = "secret-token"

};

logger.LogInformation("Processing request: {Request}", request); // 杈撳嚭: Processing request: HttpRequest


### 鍦烘櫙 2锛氬崟鍏冩祴璇曟柇瑷€

**闇€姹?*锛氬湪娴嬭瘯涓瘮杈冨璞$姸鎬併€?

```csharp
[GenerateToString]
public partial class UserDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

// 娴嬭瘯浠g爜
[Fact]
public void CreateUser_ShouldReturnCorrectDto()
{
    var result = userService.CreateUser("John", "john@example.com");
    
    var expected = new UserDto
    {
        Id = 1,
        Name = "John",
        Email = "john@example.com"
    };
    
    // ToString 浣挎祴璇曞け璐ユ秷鎭洿娓呮櫚
    Assert.Equal(expected.ToString(), result.ToString());
    // 澶辫触鏃惰緭鍑? Expected: UserDto { Id = 1, Name = John, Email = john@example.com }
    //           Actual: UserDto { Id = 2, Name = John, Email = john@example.com }
}

鍦烘櫙 3锛氳皟璇曞鏉傚璞?

**闇€姹?*锛氬湪璋冭瘯鍣ㄤ腑蹇€熸煡鐪嬪璞$姸鎬併€?

csharp
[GenerateToString]
public partial class OrderSummary
{
    public int OrderId { get; set; }
    public string CustomerName { get; set; }
    public decimal TotalAmount { get; set; }
    public List<string> Items { get; set; }
    public DateTime OrderDate { get; set; }
}

// 鍦ㄨ皟璇曞櫒鐨?Watch 绐楀彛涓紝鐩存帴鏄剧ず瀹屾暣淇℃伅
// OrderSummary { OrderId = 123, CustomerName = John, TotalAmount = 99.99, Items = [Item1, Item2], OrderDate = 2025-01-21 }

鍦烘櫙 4锛氶厤缃璞¢獙璇?

**闇€姹?*锛氶獙璇侀厤缃璞℃槸鍚︽纭姞杞姐€?

csharp
[GenerateToString]
public partial class AppSettings
{
    public string DatabaseConnection { get; set; }
    public int MaxRetries { get; set; }
    public TimeSpan Timeout { get; set; }
    
    [ToStringIgnore]
    public string ApiKey { get; set; }  // 鏁忔劅淇℃伅
}

// 鍚姩鏃堕獙璇侀厤缃?
public void ConfigureServices(IServiceCollection services)
{
    var settings = Configuration.Get<AppSettings>();
    
    logger.LogInformation("Loaded settings: {Settings}", settings);
    // 杈撳嚭: Loaded settings: AppSettings { DatabaseConnection = Server=localhost, MaxRetries = 3, Timeout = 00:00:30 }
    
    if (string.IsNullOrEmpty(settings.DatabaseConnection))
    {
        throw new InvalidOperationException($"Invalid settings: {settings}");
    }
}

鍦烘櫙 5锛欰PI 鍝嶅簲璋冭瘯

**闇€姹?*锛氳褰?API 鍝嶅簲鍐呭锛屾柟渚挎帓鏌ラ棶棰樸€?

csharp
[GenerateToString]
public partial class ApiResponse<T>
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public T Data { get; set; }
    public List<string> Errors { get; set; }
}

// 浣跨敤
public async Task<ApiResponse<User>> GetUserAsync(int id)
{
    var response = await httpClient.GetAsync($"/api/users/{id}");
    var result = await response.Content.ReadFromJsonAsync<ApiResponse<User>>();
    
    logger.LogDebug("API response: {Response}", result);
    // 杈撳嚭: API response: ApiResponse { Success = True, Message = OK, Data = User { Id = 1, Name = John }, Errors = [] }
    
    return result;
}

鏈€浣冲疄璺?vs 鍙嶆ā寮?

瀵规瘮琛ㄦ牸

鏂归潰鉁?鏈€浣冲疄璺?鉂?鍙嶆ā寮?鍘熷洜
绫讳慨楗扮浣跨敤 partial 绫?涓嶄娇鐢?partial鐢熸垚鍣ㄩ渶瑕?partial 鎵嶈兘娣诲姞鏂规硶
鎬ц兘浣跨敤 StringBuilder浣跨敤瀛楃涓叉嫾鎺?StringBuilder 閬垮厤澶ч噺鍐呭瓨鍒嗛厤
null 澶勭悊妫€鏌ュ苟澶勭悊 null涓嶅鐞?null閬垮厤 NullReferenceException
鏁忔劅淇℃伅浣跨敤 [ToStringIgnore]鍖呭惈瀵嗙爜绛夋晱鎰熶俊鎭?淇濇姢瀹夊叏
闆嗗悎鏍煎紡鍖栭泦鍚堝唴瀹?鐩存帴杈撳嚭闆嗗悎绫诲瀷鍚?鎻愪緵鏈夌敤淇℃伅
宓屽瀵硅薄璋冪敤宓屽瀵硅薄鐨?ToString杈撳嚭绫诲瀷鍚?鏄剧ず瀹屾暣淇℃伅
鏍煎紡浣跨敤娓呮櫚鐨勬牸寮?鏃犳牸寮忔垨娣蜂贡鏍煎紡鎻愰珮鍙鎬?
鍛藉悕绌洪棿浣跨敤瀹屾暣鍛藉悕绌洪棿浣跨敤 using 鎸囦护閬垮厤鍐茬獊

璇︾粏绀轰緥

1. Partial 绫?

csharp
// 鉂?鍙嶆ā寮忥細涓嶄娇鐢?partial
[GenerateToString]
public class Person  // 缂栬瘧閿欒锛?
{
    public string Name { get; set; }
}

// 鉁?鏈€浣冲疄璺碉細浣跨敤 partial
[GenerateToString]
public partial class Person
{
    public string Name { get; set; }
}

2. 鎬ц兘浼樺寲

csharp
// 鉂?鍙嶆ā寮忥細瀛楃涓叉嫾鎺?
public override string ToString()
{
    return "Person { " +
           "Name = " + Name + ", " +
           "Age = " + Age + ", " +
           "Email = " + Email +
           " }";
}

// 鉁?鏈€浣冲疄璺碉細StringBuilder
public override string ToString()
{
    var sb = new StringBuilder();
    sb.Append("Person { ");
    sb.Append("Name = ");
    sb.Append(Name);
    sb.Append(", Age = ");
    sb.Append(Age);
    sb.Append(", Email = ");
    sb.Append(Email);
    sb.Append(" }");
    return sb.ToString();
}

3. Null 澶勭悊

csharp
// 鉂?鍙嶆ā寮忥細涓嶅鐞?null
public override string ToString()
{
    return $"Person {{ Name = {Name}, Email = {Email} }}";
    // 濡傛灉 Name 鎴?Email 鏄?null锛岃緭鍑?"Person { Name = , Email =  }"
}

// 鉁?鏈€浣冲疄璺碉細澶勭悊 null
public override string ToString()
{
    var sb = new StringBuilder();
    sb.Append("Person { ");
    sb.Append("Name = ");
    sb.Append(Name ?? "null");
    sb.Append(", Email = ");
    sb.Append(Email ?? "null");
    sb.Append(" }");
    return sb.ToString();
}

4. 鏁忔劅淇℃伅淇濇姢

csharp
// 鉂?鍙嶆ā寮忥細鍖呭惈鏁忔劅淇℃伅
[GenerateToString]
public partial class User
{
    public string Username { get; set; }
    public string Password { get; set; }  // 鍗遍櫓锛?
    public string CreditCard { get; set; }  // 鍗遍櫓锛?
}

// 鉁?鏈€浣冲疄璺碉細蹇界暐鏁忔劅淇℃伅
[GenerateToString]
public partial class User
{
    public string Username { get; set; }
    
    [ToStringIgnore]
    public string Password { get; set; }
    
    [ToStringIgnore]
    public string CreditCard { get; set; }
}

5. 闆嗗悎鏍煎紡鍖?

csharp
// 鉂?鍙嶆ā寮忥細涓嶆牸寮忓寲闆嗗悎
public override string ToString()
{
    return $"Order {{ Items = {Items} }}";
    // 杈撳嚭: Order { Items = System.Collections.Generic.List`1[Item] }
}

// 鉁?鏈€浣冲疄璺碉細鏍煎紡鍖栭泦鍚?
public override string ToString()
{
    var sb = new StringBuilder();
    sb.Append("Order { Items = [");
    if (Items != null)
    {
        sb.Append(string.Join(", ", Items.Select(x => x.ToString())));
    }
    sb.Append("] }");
    return sb.ToString();
}

6. 宓屽瀵硅薄

csharp
// 鉂?鍙嶆ā寮忥細涓嶅鐞嗗祵濂楀璞?
public override string ToString()
{
    return $"Order {{ Customer = {Customer} }}";
    // 杈撳嚭: Order { Customer = MyApp.Customer }
}

// 鉁?鏈€浣冲疄璺碉細璋冪敤宓屽瀵硅薄鐨?ToString
public override string ToString()
{
    var sb = new StringBuilder();
    sb.Append("Order { Customer = ");
    sb.Append(Customer?.ToString() ?? "null");
    sb.Append(" }");
    return sb.ToString();
}

鎬ц兘浼樺寲

浼樺寲绛栫暐

浼樺寲 1锛氫娇鐢?StringBuilder

csharp
// 鎬ц兘娴嬭瘯缁撴灉锛?0000 娆¤皟鐢級
// 瀛楃涓叉嫾鎺? 150ms, 鍒嗛厤 2.5MB
// StringBuilder: 50ms, 鍒嗛厤 0.8MB

// 鉁?鎺ㄨ崘
public override string ToString()
{
    var sb = new StringBuilder(100);  // 棰勫垎閰嶅閲?
    sb.Append("Person { ");
    sb.Append("Name = ");
    sb.Append(Name);
    sb.Append(" }");
    return sb.ToString();
}

浼樺寲 2锛氱紦瀛樻牸寮忓瓧绗︿覆

csharp
// 瀵逛簬鍥哄畾鏍煎紡锛屽彲浠ョ紦瀛樻牸寮忓瓧绗︿覆
private static readonly string FormatString = "Person {{ Name = {0}, Age = {1} }}";

public override string ToString()
{
    return string.Format(FormatString, Name, Age);
}

浼樺寲 3锛氬欢杩熸牸寮忓寲

csharp
// 鍙湪闇€瑕佹椂鏍煎紡鍖栭泦鍚?
public override string ToString()
{
    var sb = new StringBuilder();
    sb.Append("Order { ");
    
    if (Items != null && Items.Count > 0)
    {
        sb.Append("Items = [");
        sb.Append(string.Join(", ", Items));
        sb.Append("]");
    }
    else
    {
        sb.Append("Items = []");
    }
    
    sb.Append(" }");
    return sb.ToString();
}

浼樺寲 4锛氶伩鍏嶈绠?

csharp
// 鉂?閬垮厤锛氬€肩被鍨嬭绠?
sb.Append(Age);  // int 瑁呯涓?object

// 鉁?鎺ㄨ崘锛氫娇鐢ㄤ笓闂ㄧ殑閲嶈浇
sb.Append(Age.ToString());  // 鎴栬€?sb.Append(Age) 濡傛灉鏈?int 閲嶈浇

鎬ц兘瀵规瘮

鏂规硶鏃堕棿 (10000娆?鍐呭瓨鍒嗛厤鎺ㄨ崘
瀛楃涓叉嫾鎺?150ms2.5MB鉂?
String.Format100ms1.8MB鈿狅笍
StringBuilder50ms0.8MB鉁?
StringBuilder (棰勫垎閰?40ms0.6MB鉁呪渽

甯歌闂

1. 涓轰粈涔堝繀椤讳娇鐢?partial 绫伙紵

闂锛氫笉浣跨敤 partial 浼氬鑷寸紪璇戦敊璇€?

鍘熷洜锛氱敓鎴愬櫒鐢熸垚鐨勪唬鐮侀渶瑕佷笌鐢ㄦ埛浠g爜鍚堝苟鎴愪竴涓被銆侰# 鍙厑璁搁€氳繃 partial 鍏抽敭瀛楀垎鍓茬被瀹氫箟銆?

瑙e喅鏂规锛?

csharp
// 鉁?姝g‘
[GenerateToString]
public partial class Person
{
    public string Name { get; set; }
}

// 鉂?閿欒
[GenerateToString]
public class Person  // 缂哄皯 partial
{
    public string Name { get; set; }
}

2. 濡備綍澶勭悊缁ф壙鐨勫睘鎬э紵

闂锛氶粯璁ゅ彧鍖呭惈褰撳墠绫荤殑灞炴€э紝涓嶅寘鍚熀绫诲睘鎬с€?

瑙e喅鏂规锛?

csharp
// 鏂规 1锛氫娇鐢ㄧ壒鎬у弬鏁?
[GenerateToString(IncludeBaseProperties = true)]
public partial class Product : BaseEntity
{
    public string Name { get; set; }
}

// 鏂规 2锛氬湪鐢熸垚鍣ㄤ腑閫掑綊鑾峰彇鍩虹被灞炴€?
private static ImmutableArray<PropertyInfo> GetAllProperties(INamedTypeSymbol symbol)
{
    var properties = new List<PropertyInfo>();
    
    // 鑾峰彇鍩虹被灞炴€?
    if (symbol.BaseType != null && symbol.BaseType.SpecialType != SpecialType.System_Object)
    {
        properties.AddRange(GetAllProperties(symbol.BaseType));
    }
    
    // 鑾峰彇褰撳墠绫诲睘鎬?
    properties.AddRange(
        symbol.GetMembers()
            .OfType<IPropertySymbol>()
            .Where(p => p.DeclaredAccessibility == Accessibility.Public)
            .Select(p => new PropertyInfo(p.Name, p.Type.ToDisplayString(), false))
    );
    
    return properties.ToImmutableArray();
}

3. 濡備綍澶勭悊寰幆寮曠敤锛?

闂锛氬祵濂楀璞″彲鑳藉鑷村惊鐜紩鐢紝閫犳垚鏍堟孩鍑恒€?

csharp
public partial class Person
{
    public string Name { get; set; }
    public Person Spouse { get; set; }  // 寰幆寮曠敤
}

瑙e喅鏂规锛?

csharp
// 鏂规 1锛氫娇鐢?ToStringIgnore
public partial class Person
{
    public string Name { get; set; }
    
    [ToStringIgnore]
    public Person Spouse { get; set; }
}

// 鏂规 2锛氬彧鏄剧ず ID
public partial class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? SpouseId { get; set; }  // 浣跨敤 ID 鑰屼笉鏄璞″紩鐢?
}

// 鏂规 3锛氬湪鐢熸垚鐨勪唬鐮佷腑妫€娴嬪惊鐜?
private static readonly ThreadLocal<HashSet<object>> _visitedObjects = 
    new ThreadLocal<HashSet<object>>(() => new HashSet<object>());

public override string ToString()
{
    if (!_visitedObjects.Value.Add(this))
    {
        return $"Person {{ Id = {Id} }} (circular reference)";
    }
    
    try
    {
        var sb = new StringBuilder();
        sb.Append("Person { ");
        sb.Append($"Name = {Name}, ");
        sb.Append($"Spouse = {Spouse?.ToString() ?? "null"}");
        sb.Append(" }");
        return sb.ToString();
    }
    finally
    {
        _visitedObjects.Value.Remove(this);
    }
}

4. 濡備綍鑷畾涔夋牸寮忥紵

闂锛氶粯璁ゆ牸寮忎笉婊¤冻闇€姹傘€?

瑙e喅鏂规锛?

csharp
// 鏂规 1锛氫娇鐢?Format 鍙傛暟
[GenerateToString(Format = "{Name} ({Age} years old)")]
public partial class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// 鏂规 2锛氭墜鍔ㄥ疄鐜?ToString
public partial class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    // 涓嶄娇鐢ㄧ敓鎴愬櫒锛屾墜鍔ㄥ疄鐜?
    public override string ToString()
    {
        return $"{Name} ({Age} years old)";
    }
}

// 鏂规 3锛氬疄鐜拌嚜瀹氫箟鏍煎紡鍖栨柟娉?
[GenerateToString]
public partial class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    // 鐢熸垚鍣ㄧ敓鎴?ToString()
    // 鎵嬪姩娣诲姞鑷畾涔夋牸寮忓寲鏂规硶
    public string ToShortString()
    {
        return $"{Name} ({Age})";
    }
}

5. 鐢熸垚鐨勪唬鐮佹湁缂栬瘧閿欒鎬庝箞鍔烇紵

璋冭瘯姝ラ锛?

  1. **鏌ョ湅鐢熸垚鐨勬枃浠?*锛?

    obj/Debug/net8.0/generated/ToStringGenerator.Generator/ToStringGenerator/ClassName.ToString.g.cs
  2. **妫€鏌ヨ娉曢敊璇?*锛?

    csharp
    // 鍦ㄧ敓鎴愬櫒涓獙璇佺敓鎴愮殑浠g爜
    var tree = CSharpSyntaxTree.ParseText(generatedCode);
    var diagnostics = tree.GetDiagnostics();
    
    if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
    {
        // 鎶ュ憡閿欒
        foreach (var diagnostic in diagnostics)
        {
            context.ReportDiagnostic(Diagnostic.Create(
                new DiagnosticDescriptor(
                    "TSG001",
                    "Generated code has syntax error",
                    diagnostic.GetMessage(),
                    "ToStringGenerator",
                    DiagnosticSeverity.Error,
                    true
                ),
                Location.None
            ));
        }
    }
  3. 娣诲姞璇婃柇鏃ュ織锛?

    csharp
    private static void GenerateToStringMethod(
        SourceProductionContext context,
        ClassInfo classInfo)
    {
        try
        {
            var source = GenerateCode(classInfo);
            context.AddSource($"{classInfo.Name}.ToString.g.cs", source);
        }
        catch (Exception ex)
        {
            context.ReportDiagnostic(Diagnostic.Create(
                new DiagnosticDescriptor(
                    "TSG002",
                    "Code generation failed",
                    $"Failed to generate ToString for {classInfo.Name}: {ex.Message}",
                    "ToStringGenerator",
                    DiagnosticSeverity.Error,
                    true
                ),
                Location.None
            ));
        }
    }

6. 濡備綍娴嬭瘯鐢熸垚鍣紵

鎺ㄨ崘鏂规硶锛?

csharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;

public class ToStringGeneratorTests
{
    [Fact]
    public void GeneratesToString_ForSimpleClass()
    {
        // 杈撳叆浠g爜
        var source = @"
using ToStringGenerator;

namespace TestNamespace
{
    [GenerateToString]
    public partial class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}";

        // 杩愯鐢熸垚鍣?
        var (diagnostics, output) = GetGeneratedOutput(source);

        // 楠岃瘉娌℃湁閿欒
        Assert.Empty(diagnostics);

        // 楠岃瘉鐢熸垚鐨勪唬鐮?
        Assert.Contains("public override string ToString()", output);
        Assert.Contains("Name = ", output);
        Assert.Contains("Age = ", output);
    }

    private (ImmutableArray<Diagnostic>, string) GetGeneratedOutput(string source)
    {
        var syntaxTree = CSharpSyntaxTree.ParseText(source);
        var references = AppDomain.CurrentDomain.GetAssemblies()
            .Where(a => !a.IsDynamic && !string.IsNullOrWhiteSpace(a.Location))
            .Select(a => MetadataReference.CreateFromFile(a.Location))
            .ToList();

        var compilation = CSharpCompilation.Create(
            "TestAssembly",
            new[] { syntaxTree },
            references,
            new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
        );

        var generator = new ToStringGenerator();
        var driver = CSharpGeneratorDriver.Create(generator);
        driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics);

        var output = outputCompilation.SyntaxTrees
            .Skip(1)  // 璺宠繃鍘熷浠g爜
            .FirstOrDefault()
            ?.ToString() ?? "";

        return (diagnostics, output);
    }
}

7. 鎬ц兘闂鎬庝箞鍔烇紵

浼樺寲姝ラ锛?

  1. 浣跨敤 StringBuilder锛氶伩鍏嶅瓧绗︿覆鎷兼帴
  2. **棰勫垎閰嶅閲?*锛歚new StringBuilder(estimatedSize)`
  3. 缂撳瓨缁撴灉锛氬鏋滃璞′笉鍙彉锛屽彲浠ョ紦瀛?ToString 缁撴灉
  4. **寤惰繜鏍煎紡鍖?*锛氬彧鍦ㄩ渶瑕佹椂鏍煎紡鍖栧鏉傚璞?
csharp
// 浼樺寲绀轰緥
public partial class Person
{
    private string? _cachedToString;

    public override string ToString()
    {
        if (_cachedToString != null)
            return _cachedToString;

        var sb = new StringBuilder(100);  // 棰勫垎閰?
        sb.Append("Person { ");
        sb.Append("Name = ");
        sb.Append(Name);
        sb.Append(", Age = ");
        sb.Append(Age);
        sb.Append(" }");

        _cachedToString = sb.ToString();
        return _cachedToString;
    }
}

8. 濡備綍澶勭悊澶у瀷瀵硅薄锛?

绛栫暐锛?

csharp
// 鏂规 1锛氶檺鍒惰緭鍑洪暱搴?
[GenerateToString(MaxLength = 1000)]
public partial class LargeObject
{
    public string Data { get; set; }  // 鍙兘寰堝ぇ
}

// 鐢熸垚鐨勪唬鐮侊細
public override string ToString()
{
    var result = $"LargeObject {{ Data = {Data} }}";
    if (result.Length > 1000)
    {
        return result.Substring(0, 1000) + "...";
    }
    return result;
}

// 鏂规 2锛氬彧鍖呭惈鎽樿淇℃伅
[GenerateToString(IncludeFields = false)]
public partial class LargeObject
{
    public int Id { get; set; }
    public int ItemCount { get; set; }
    
    [ToStringIgnore]
    public byte[] LargeData { get; set; }  // 蹇界暐澶ф暟鎹?
}

鎵╁睍缁冧範

缁冧範 1锛氭坊鍔犳牸寮忓寲閫夐」

浠诲姟锛氭敮鎸佷笉鍚岀殑鏃ユ湡鏃堕棿鏍煎紡銆?

csharp
[GenerateToString(DateTimeFormat = "yyyy-MM-dd HH:mm:ss")]
public partial class Event
{
    public string Name { get; set; }
    public DateTime StartTime { get; set; }
}

缁冧範 2锛氭敮鎸佸璇█

浠诲姟锛氭牴鎹綋鍓嶆枃鍖栫敓鎴愭湰鍦板寲鐨?ToString銆?

csharp
[GenerateToString(Localized = true)]
public partial class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// 杈撳嚭锛堜腑鏂囷級锛氫骇鍝?{ 鍚嶇О = iPhone, 浠锋牸 = 楼5999 }
// 杈撳嚭锛堣嫳鏂囷級锛歅roduct { Name = iPhone, Price = $999 }

缁冧範 3锛氭坊鍔?JSON 鏍煎紡

浠诲姟锛氱敓鎴?JSON 鏍煎紡鐨勫瓧绗︿覆琛ㄧず銆?

csharp
[GenerateToString(Format = ToStringFormat.Json)]
public partial class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// 杈撳嚭锛歿"Name":"John","Age":30}

缁冧範 4锛氭敮鎸佹潯浠跺寘鍚?

浠诲姟锛氭牴鎹潯浠跺喅瀹氭槸鍚﹀寘鍚煇浜涘睘鎬с€?

csharp
[GenerateToString]
public partial class User
{
    public string Username { get; set; }
    
    [ToStringIncludeIf("IsDebugMode")]
    public string InternalId { get; set; }  // 鍙湪璋冭瘯妯″紡涓嬪寘鍚?
}

缁冧範 5锛氭€ц兘鍒嗘瀽

浠诲姟锛氭瘮杈冧笉鍚屽疄鐜扮殑鎬ц兘銆?

csharp
[Benchmark]
public class ToStringBenchmark
{
    private Person person;

    [GlobalSetup]
    public void Setup()
    {
        person = new Person { Name = "John", Age = 30, Email = "john@example.com" };
    }

    [Benchmark]
    public string StringConcatenation()
    {
        return "Person { Name = " + person.Name + ", Age = " + person.Age + " }";
    }

    [Benchmark]
    public string StringFormat()
    {
        return string.Format("Person {{ Name = {0}, Age = {1} }}", person.Name, person.Age);
    }

    [Benchmark]
    public string StringBuilder()
    {
        var sb = new StringBuilder();
        sb.Append("Person { Name = ");
        sb.Append(person.Name);
        sb.Append(", Age = ");
        sb.Append(person.Age);
        sb.Append(" }");
        return sb.ToString();
    }

    [Benchmark]
    public string GeneratedToString()
    {
        return person.ToString();
    }
}

馃敆 鐩稿叧璧勬簮

娣卞叆瀛︿範

  • [蹇€熷紑濮媇(../guide/getting-started.md) - 寮€濮嬩娇鐢ㄦ簮鐢熸垚鍣?
  • Hello World 绀轰緥 - 鏈€绠€鍗曠殑鍏ラ棬绀轰緥
  • [澧為噺鐢熸垚鍣ㄧず渚媇(./incremental-generator.md) - 瀛︿範澧為噺鐢熸垚鍣ㄧ殑浣跨敤
  • [Builder 鐢熸垚鍣╙(./builder-generator.md) - 澶嶆潅鐨勪唬鐮佺敓鎴愭ā寮?
  • 娴嬭瘯绀轰緥 - 浜嗚В濡備綍娴嬭瘯婧愮敓鎴愬櫒

API 鍙傝€?

  • 浠g爜鐢熸垚 API - 浠g爜鐢熸垚 API 鍙傝€?
  • 璇箟妯″瀷 API - 璇箟妯″瀷 API 璇︾粏鍙傝€?
  • [鏈€浣冲疄璺礭(../api/best-practices.md) - 婧愮敓鎴愬櫒寮€鍙戞渶浣冲疄璺?

瀹樻柟鏂囨。

鐩稿叧鏂囨。

  • [澧為噺鐢熸垚鍣ㄧず渚媇(/examples/incremental-generator) - 瀛︿範澧為噺鐢熸垚鍣?
  • [Builder 鐢熸垚鍣╙(/examples/builder-generator) - 鏇村鏉傜殑浠g爜鐢熸垚
  • 浠g爜鐢熸垚 API - 浠g爜鐢熸垚鎶€宸?
  • [鏈€浣冲疄璺礭(/api/best-practices) - 鎬ц兘浼樺寲寤鸿

绀轰緥椤圭洰

宸ュ叿鍜屽簱

涓嬩竴姝ュ涔?

  1. 鍩虹宸╁浐锛?

  2. 杩涢樁瀛︿範锛?

    • 瀛︿範 [Builder 鐢熸垚鍣╙(/examples/builder-generator)
    • 瀹炶返 璇婃柇鎶ュ憡
    • 鎺屾彙 [娴嬭瘯鎶€鏈痌(/examples/testing)
  3. **娣卞叆鐮旂┒**锛?


鎬荤粨

ToString 鐢熸垚鍣ㄦ槸涓€涓疄鐢ㄧ殑婧愮敓鎴愬櫒绀轰緥锛屽睍绀轰簡濡備綍锛?

  1. **浣跨敤鐗规€ф爣璁?*锛氶€氳繃鐗规€ф帶鍒朵唬鐮佺敓鎴?
  2. **鍒嗘瀽绫荤粨鏋?*锛氭彁鍙栧睘鎬у拰瀛楁淇℃伅
  3. 鐢熸垚鏂规硶浠g爜锛氬垱寤?ToString 鏂规硶瀹炵幇
  4. 澶勭悊澶嶆潅绫诲瀷锛氭敮鎸佸祵濂楀璞″拰闆嗗悎
  5. 鎬ц兘浼樺寲锛氫娇鐢?StringBuilder 鎻愰珮鎬ц兘

閫氳繃瀛︿範杩欎釜绀轰緥锛屼綘鍙互鎺屾彙婧愮敓鎴愬櫒鐨勬牳蹇冩妧鏈紝骞跺簲鐢ㄥ埌鍏朵粬浠g爜鐢熸垚鍦烘櫙涓€?

鏂囨。瀛楁暟缁熻锛氱害 7,200 瀛?

4. 濡備綍鑷畾涔夊睘鎬х殑鏍煎紡鍖栵紵

闂锛氶渶瑕佸涓嶅悓绫诲瀷鐨勫睘鎬т娇鐢ㄤ笉鍚岀殑鏍煎紡鍖栨柟寮忋€?

瑙e喅鏂规锛氫娇鐢ㄧ壒鎬у弬鏁版寚瀹氭牸寮忓寲閫夐」

csharp
// 瀹氫箟鏍煎紡鍖栫壒鎬?
[AttributeUsage(AttributeTargets.Property)]
public class ToStringFormatAttribute : Attribute
{
    public string Format { get; }
    
    public ToStringFormatAttribute(string format)
    {
        Format = format;
    }
}

// 浣跨敤鏍煎紡鍖栫壒鎬?
[GenerateToString]
public partial class Product
{
    public string Name { get; set; }
    
    [ToStringFormat("C2")]  // 璐у竵鏍煎紡锛屼繚鐣欎袱浣嶅皬鏁?
    public decimal Price { get; set; }
    
    [ToStringFormat("yyyy-MM-dd")]  // 鏃ユ湡鏍煎紡
    public DateTime CreatedDate { get; set; }
}

// 鐢熸垚鍣ㄤ腑澶勭悊鏍煎紡鍖?
private string GeneratePropertyString(PropertyInfo property)
{
    if (property.FormatString != null)
    {
        return $"{property.Name} = {{{property.Name}:{property.FormatString}}}";
    }
    return $"{property.Name} = {{{property.Name}}}";
}

鏈€鍚庢洿鏂? 2025-01-21

Q3: 濡備綍澶勭悊寰幆寮曠敤锛?

A: 浣跨敤璁块棶璺熻釜閬垮厤鏃犻檺閫掑綊锛?

csharp
public class ToStringGenerator
{
    private readonly HashSet<object> _visited = new();
    
    public string GenerateToString(object obj)
    {
        if (obj == null)
            return "null";
        
        // 妫€鏌ユ槸鍚﹀凡璁块棶
        if (_visited.Contains(obj))
            return $"[Circular Reference: {obj.GetType().Name}]";
        
        _visited.Add(obj);
        
        try
        {
            // 鐢熸垚 ToString 浠g爜
            return GenerateToStringInternal(obj);
        }
        finally
        {
            _visited.Remove(obj);
        }
    }
}

鏈€鍚庢洿鏂? 2025-01-21

基于 MIT 许可发布