From ae24db64f5a48e97d4f618af2ae65f1bb9bf6635 Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Tue, 1 Sep 2026 22:29:42 +0300 Subject: [PATCH 1/2] first --- README.md | 30 +- later.md | 2 +- v2/.tours/TrimItEasy.tour | 30 + v2/Generator/all.csv | 1 + v2/RSCGExamplesData/GeneratorDataRec.json | 7 + v2/rscg_examples/TrimItEasy/description.json | 22 + v2/rscg_examples/TrimItEasy/nuget.txt | 1 + v2/rscg_examples/TrimItEasy/readme.txt | 286 ++++++++++ v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx | 3 + .../TrimItEasy/src/TrimDemo/Person.cs | 18 + .../TrimItEasy/src/TrimDemo/Program.cs | 7 + .../TrimItEasy/src/TrimDemo/TrimDemo.csproj | 22 + v2/rscg_examples/TrimItEasy/video.json | 39 ++ .../docs/Authors/Phong_Nguyen.md | 7 + .../docs/Categories/EnhancementClass.md | 4 +- .../Categories/_PrimitiveEnhancementClass.mdx | 2 + .../docs/RSCG-Examples/TrimItEasy.md | 529 ++++++++++++++++++ .../docs/RSCG-Examples/index.md | 13 +- v2/rscg_examples_site/docs/about.md | 2 +- v2/rscg_examples_site/docs/indexRSCG.md | 5 +- .../src/components/HomepageFeatures/index.js | 2 +- .../static/exports/RSCG.json | 8 + .../static/exports/RSCG.xlsx | Bin 14945 -> 14989 bytes 23 files changed, 1027 insertions(+), 13 deletions(-) create mode 100644 v2/.tours/TrimItEasy.tour create mode 100644 v2/rscg_examples/TrimItEasy/description.json create mode 100644 v2/rscg_examples/TrimItEasy/nuget.txt create mode 100644 v2/rscg_examples/TrimItEasy/readme.txt create mode 100644 v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx create mode 100644 v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs create mode 100644 v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs create mode 100644 v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj create mode 100644 v2/rscg_examples/TrimItEasy/video.json create mode 100644 v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md create mode 100644 v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md diff --git a/README.md b/README.md index 19e54beb8..d3304c8eb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# RSCG - 286 Examples of Roslyn Source Code Generators / 16 created by Microsoft / +# RSCG - 287 Examples of Roslyn Source Code Generators / 16 created by Microsoft / -The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 286 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. +The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 287 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem -## Latest Update : 2026-08-27 => 27 August 2026 +## Latest Update : 2026-08-28 => 28 August 2026 If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)*** @@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt ## Content -Those are the 286 Roslyn Source Code Generators that I have tested you can see and download source code example. +Those are the 287 Roslyn Source Code Generators that I have tested you can see and download source code example. ( including 16 from Microsoft ) +### 287. [TrimItEasy](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy) , in the [EnhancementClass](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementclass) category + +Generated on : 2026-08-28 => 28 August 2026 + +
+ Expand + + + +Author: Phong Nguyen + +Package Description + +Nuget: [https://www.nuget.org/packages/TrimItEasy/](https://www.nuget.org/packages/TrimItEasy/) + + +Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy) + +Source: [https://github.com/phongnguyend/TrimItEasy](https://github.com/phongnguyend/TrimItEasy) + +
+ ### 286. [SatorImaging.TDoubles](https://ignatandrei.github.io/RSCG_Examples/v2/docs/SatorImaging.TDoubles) , in the [Tests](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#tests) category Generated on : 2026-08-27 => 27 August 2026 diff --git a/later.md b/later.md index db0f7aed3..5c92ff14f 100644 --- a/later.md +++ b/later.md @@ -1,6 +1,6 @@ # Just later -## Latest Update : 2026-08-27 => 27 August 2026 +## Latest Update : 2026-08-28 => 28 August 2026 diff --git a/v2/.tours/TrimItEasy.tour b/v2/.tours/TrimItEasy.tour new file mode 100644 index 000000000..d3e903fb1 --- /dev/null +++ b/v2/.tours/TrimItEasy.tour @@ -0,0 +1,30 @@ + +{ + "$schema": "https://aka.ms/codetour-schema", + "title": "TrimItEasy", + "steps": + [ + { + "file": "rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj", + "description": "First, we add Nuget [TrimItEasy](https://www.nuget.org/packages/TrimItEasy/) in csproj ", + "pattern": "TrimItEasy" + } + + ,{ + "file": "rscg_examples/TrimItEasy/src/TrimDemo/Program.cs", + "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj ", + "pattern": "this is the code" + } + + + ,{ + "file": "rscg_examples/TrimItEasy/src/TrimDemo/obj/GX/TrimItEasy.Generators/TrimItEasy.Generators.TrimmerSourceGenerator/PersonExtensions_FastTrimStrings.g.cs", + "description": "Generated File 1 from 1 : PersonExtensions_FastTrimStrings.g.cs ", + "line": 1 + } + + ], + + "ref": "main" + +} \ No newline at end of file diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv index 8ed5de681..7a2489f21 100644 --- a/v2/Generator/all.csv +++ b/v2/Generator/all.csv @@ -285,3 +285,4 @@ Nr,Key,Source,Category 284,Pinecone.TypedPath, https://github.com/nickpinecone/typed-path,FilesToCode 285,PropertyResolvers, https://github.com/tombiddulph/PropertyResolvers,EnhancementProject 286,SatorImaging.TDoubles, https://github.com/sator-imaging/TDoubles,Tests +287,TrimItEasy, https://github.com/phongnguyend/TrimItEasy,EnhancementClass diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json index 4e0c4b142..dd12eefe5 100644 --- a/v2/RSCGExamplesData/GeneratorDataRec.json +++ b/v2/RSCGExamplesData/GeneratorDataRec.json @@ -1734,5 +1734,12 @@ "dtStart": "2026-08-27T00:00:00", "show": true } + , + { + "ID":"TrimItEasy", + "Category": 5, + "dtStart": "2026-08-28T00:00:00", + "show": true + } ] \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/description.json b/v2/rscg_examples/TrimItEasy/description.json new file mode 100644 index 000000000..e50e20f82 --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/description.json @@ -0,0 +1,22 @@ +{ + "generator":{ + "name":"TrimItEasy", + "nuget":[ + "https://www.nuget.org/packages/TrimItEasy/" + ], + "link":"https://github.com/phongnguyend/TrimItEasy", + "author":"Phong Nguyen", + "source":"https://github.com/phongnguyend/TrimItEasy" + }, + "data":{ + "goodFor":["trimming eacg string from a class properties"], + "csprojDemo":"TrimDemo.csproj", + "csFiles":["Program.cs"], + "excludeDirectoryGenerated":[""], + "includeAdditionalFiles":[""] + }, + "links":{ + "blog":"", + "video":"" + } +} \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/nuget.txt b/v2/rscg_examples/TrimItEasy/nuget.txt new file mode 100644 index 000000000..882e74f60 --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/nuget.txt @@ -0,0 +1 @@ +Package Description \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/readme.txt b/v2/rscg_examples/TrimItEasy/readme.txt new file mode 100644 index 000000000..4c39f2b43 --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/readme.txt @@ -0,0 +1,286 @@ +# TrimItEasy + +A simple and efficient .NET library for automatically trimming string properties in complex objects. + +## Installation + +Install the package from NuGet: + +```bash +dotnet add package TrimItEasy +``` + +Or using the NuGet Package Manager in Visual Studio: +``` +Install-Package TrimItEasy +``` + +## Usage + +### Basic Usage + +Simply call the `TrimStrings()` extension method on any complex object: + +```csharp +using TrimItEasy; + +public class Person +{ + public string Name { get; set; } + + public string Email { get; set; } + + public Address HomeAddress { get; set; } +} + +var person = new Person +{ + Name = " John Doe ", + Email = " john@example.com ", + HomeAddress = new Address + { + Street = " 123 Main St ", + City = " New York " + } +}; + +// Trim all string properties +person.TrimStrings(); +``` + +### Skip Trimming Specific Properties + +Use the `[NotTrimmed]` attribute to prevent trimming of specific properties: + +```csharp +public class Address +{ + [NotTrimmed] + public string Street { get; set; } // This property will not be trimmed + + public string City { get; set; } // This property will be trimmed +} + +var address = new Address +{ + Street = " 123 Main St, Apt 4B ", // Will remain unchanged + City = " New York " // Will be trimmed to "New York" +}; + +address.TrimStrings(); +``` + +### Recursive Trimming + +By default, the library recursively trims all string properties in nested objects up to a maximum depth of 64 levels. You can customize this behavior using `TrimmingOptions`: + +```csharp +// Only trim top-level string properties (disable recursion) +person.TrimStrings(new TrimmingOptions { Recursive = false }); + +// Limit recursion to 2 levels of nested objects +person.TrimStrings(new TrimmingOptions { MaxDepth = 2 }); + +// Only trim the top-level object's string properties (no nested objects) +person.TrimStrings(new TrimmingOptions { MaxDepth = 0 }); +``` + +| Option | Type | Default | Description | +|-------------|--------|---------|------------------------------------------------------------------------------------------------------| +| `Recursive` | `bool` | `true` | Whether to trim strings in nested objects. When `false`, only top-level string properties are trimmed.| +| `MaxDepth` | `int` | `64` | Maximum depth for recursive trimming. `0` trims only top-level properties, `1` includes one level of nested objects, and so on. | + +### Supported Types + +The library works with: +- Complex objects with string properties +- Collections (Lists, Arrays, etc.) +- Nested objects +- Properties marked with `[NotTrimmed]` will be skipped + +### Limitations + +The library will throw an `ArgumentException` if you try to use it on: +- String types (use `string.Trim()` instead) +- Primitive types +- Enum types + +## Examples + +### Working with Collections + +```csharp +public class Company +{ + public string Name { get; set; } + + public List Employees { get; set; } +} + +public class Employee +{ + public string Name { get; set; } + + [NotTrimmed] + public string EmployeeId { get; set; } +} + +var company = new Company +{ + Name = " Acme Corp ", + Employees = new List + { + new Employee { Name = " John Doe ", EmployeeId = " E001 " }, + new Employee { Name = " Jane Smith ", EmployeeId = " E002 " } + } +}; + +company.TrimStrings(); +// Result: +// - company.Name = "Acme Corp" +// - company.Employees[0].Name = "John Doe" +// - company.Employees[0].EmployeeId = " E001 " (not trimmed due to [NotTrimmed]) +``` + +### Working with Nested Objects + +```csharp +public class Order +{ + public string OrderNumber { get; set; } + + public Customer Customer { get; set; } + + public List Items { get; set; } +} + +public class Customer +{ + public string Name { get; set; } + + [NotTrimmed] + public string PhoneNumber { get; set; } +} + +var order = new Order +{ + OrderNumber = " ORD-001 ", + Customer = new Customer + { + Name = " John Doe ", + PhoneNumber = " +1 (555) 123-4567 " + }, + Items = new List + { + new OrderItem { Description = " Product A " } + } +}; + +order.TrimStrings(); +// All string properties will be trimmed except Customer.PhoneNumber +``` + +### Source Generator (Zero Reflection) + +For maximum performance, TrimItEasy includes a source generator that produces optimized trimming code at compile time � no reflection at runtime. + +#### Installation + +Install both the core library and the source generator package: + +```bash +dotnet add package TrimItEasy +dotnet add package TrimItEasy.Generators +``` + +Or using the NuGet Package Manager in Visual Studio: +``` +Install-Package TrimItEasy +Install-Package TrimItEasy.Generators +``` + +> **Note:** The `TrimItEasy.Generators` package must be referenced as an analyzer. If you are referencing the project directly, use: +> ```xml +> OutputItemType="Analyzer" +> ReferenceOutputAssembly="false" /> +> ``` + +#### Usage + +1. **Define a `static partial` extension method** that takes your target type as a `this` parameter and returns `void`. +2. **Annotate it with `[GeneratedTrimming]`**. + +The source generator will implement the method body automatically. + +```csharp +using TrimItEasy; + +public class Person +{ + public string Name { get; set; } + public string Email { get; set; } + public Address HomeAddress { get; set; } + public List Phones { get; set; } +} + +public class Address +{ + public string Street { get; set; } + public string City { get; set; } +} + +public class Phone +{ + public string Type { get; set; } + public string Number { get; set; } +} + +// Define the partial method � the source generator fills in the implementation +public static partial class PersonExtensions +{ + [GeneratedTrimming] + public static partial void FastTrimStrings(this Person person); + + [GeneratedTrimming] + public static partial void FastTrimStringsWithOptions(this Person person, TrimmingOptions? options = null); +} +``` + +Then simply call the generated method: + +```csharp +var person = new Person +{ + Name = " John Doe ", + Email = " john@example.com ", + HomeAddress = new Address + { + Street = " 123 Main St ", + City = " New York " + }, + Phones = new List + { + new Phone { Type = " Mobile ", Number = " 123-456-7890 " } + } +}; + +person.FastTrimStrings(); +// All string properties are trimmed, including nested objects and collections +``` + +#### How It Works + +- The source generator analyzes the target type's property graph at compile time. +- It generates a dedicated trimming method that directly accesses each string property � no reflection involved. +- Nested objects and collections (`List`, arrays, etc.) are handled recursively. +- Properties marked with `[NotTrimmed]` are respected and skipped. +- Circular references are detected and handled safely using a visited set. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx b/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx new file mode 100644 index 000000000..1ce7224a4 --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx @@ -0,0 +1,3 @@ + + + diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs new file mode 100644 index 000000000..c61bf8e96 --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs @@ -0,0 +1,18 @@ +using TrimItEasy; + +namespace TrimDemo; + +public partial class Person +{ + public int Id { get; set; } + + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; }= string.Empty; + +} + +public static partial class PersonExtensions +{ + [GeneratedTrimming] + public static partial void FastTrimStrings(this Person person); +} \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs new file mode 100644 index 000000000..f546179fc --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs @@ -0,0 +1,7 @@ +using TrimDemo; + +Person p = new(); +p.FirstName = " Andrei "; +p.LastName = " Ignat "; +p.FastTrimStrings(); +Console.WriteLine(p.FirstName + " " + p.LastName); \ No newline at end of file diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj b/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj new file mode 100644 index 000000000..534ec57af --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj @@ -0,0 +1,22 @@ + + + + Exe + net10.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + true + $(BaseIntermediateOutputPath)\GX + + + diff --git a/v2/rscg_examples/TrimItEasy/video.json b/v2/rscg_examples/TrimItEasy/video.json new file mode 100644 index 000000000..f1bb23c9f --- /dev/null +++ b/v2/rscg_examples/TrimItEasy/video.json @@ -0,0 +1,39 @@ +{ + "scriptName": "TrimItEasy", + "steps": +[ + {"typeStep":"exec","arg":"clipchamp.exe launch"}, + {"typeStep":"text","arg": "Welcome to Roslyn Examples"}, + {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"}, + {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"}, + {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "}, + +{"typeStep":"text","arg": "Today I will present TrimItEasy . trimming eacg string from a class properties ."}, +{"typeStep":"browser","arg":"https://www.nuget.org/packages/TrimItEasy/"}, +{"typeStep":"text","arg": "The whole example is here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy"}, +{"typeStep":"text","arg": "You can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy#download-example-net--c-"}, +{"typeStep":"text","arg":"Here is the code downloaded "}, +{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"}, +{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "}, +{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"}, + +{"typeStep":"text","arg": "To use it ,you will put the Nuget TrimItEasy into the csproj "}, + +{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\TrimItEasy\\src\\TrimDemo\\TrimDemo.csproj"}, + +{"typeStep":"text","arg": "And now I will show you an example of using TrimItEasy"}, + +{"typeStep":"hide","arg": "now execute the tour in VSCode"}, +{"typeStep":"tour", "arg": "src/.tours/"}, +{"typeStep":"text","arg":" And I will execute the project"}, +{"typeStep":"showproj", "arg":"TrimDemo.csproj"}, +{"typeStep":"text","arg":" This concludes the project"}, +{"typeStep":"waitseconds","arg":"30"}, +{"typeStep":"text","arg": "Remember, you can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy#download-example-net--c-", +SpeakTest=" "}, +{"typeStep":"waitseconds","arg":"30"}, +] +} diff --git a/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md b/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md new file mode 100644 index 000000000..421735cfe --- /dev/null +++ b/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md @@ -0,0 +1,7 @@ +# Author : Phong Nguyen + +Number RSCG: 1 + + + 1 [TrimItEasy](/docs/TrimItEasy) [![Nuget](https://img.shields.io/nuget/dt/TrimItEasy?label=TrimItEasy)](https://www.nuget.org/packages/TrimItEasy/) ![GitHub Repo stars](https://img.shields.io/github/stars/phongnguyend/TrimItEasy?style=social) 2026-08-28 + diff --git a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md index 51f96ad18..1a7b9e32e 100644 --- a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md +++ b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md @@ -1,6 +1,6 @@

EnhancementClass

-Number RSCG: 30 +Number RSCG: 31 1 [ApparatusAOT](/docs/ApparatusAOT) [![Nuget](https://img.shields.io/nuget/dt/Apparatus.AOT.Reflection?label=Apparatus.AOT.Reflection)](https://www.nuget.org/packages/Apparatus.AOT.Reflection/) ![GitHub Repo stars](https://img.shields.io/github/stars/byme8/Apparatus.AOT.Reflection?style=social) 2023-04-16 @@ -61,4 +61,6 @@ Number RSCG: 30 29 [TelemetryLogging](/docs/TelemetryLogging) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Telemetry.Abstractions?label=Microsoft.Extensions.Telemetry.Abstractions)](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/extensions?style=social) 2023-11-30 30 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 2024-04-19 + + 31 [TrimItEasy](/docs/TrimItEasy) [![Nuget](https://img.shields.io/nuget/dt/TrimItEasy?label=TrimItEasy)](https://www.nuget.org/packages/TrimItEasy/) ![GitHub Repo stars](https://img.shields.io/github/stars/phongnguyend/TrimItEasy?style=social) 2026-08-28 \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx index a5701dca1..b4bc072cb 100644 --- a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx +++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx @@ -60,6 +60,8 @@ 30 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 2024-04-19 + 31 [TrimItEasy](/docs/TrimItEasy) [![Nuget](https://img.shields.io/nuget/dt/TrimItEasy?label=TrimItEasy)](https://www.nuget.org/packages/TrimItEasy/) ![GitHub Repo stars](https://img.shields.io/github/stars/phongnguyend/TrimItEasy?style=social) 2026-08-28 + ### See category [EnhancementClass](/docs/Categories/EnhancementClass) diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md new file mode 100644 index 000000000..7d8e296f6 --- /dev/null +++ b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md @@ -0,0 +1,529 @@ +--- +sidebar_position: 2870 +title: 287 - TrimItEasy +description: trimming eacg string from a class properties +slug: /TrimItEasy +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import TOCInline from '@theme/TOCInline'; +import SameCategory from '../Categories/_PrimitiveEnhancementClass.mdx'; + +# TrimItEasy by Phong Nguyen + + + + +## NuGet / site data +[![Nuget](https://img.shields.io/nuget/dt/TrimItEasy?label=TrimItEasy)](https://www.nuget.org/packages/TrimItEasy/) +[![GitHub last commit](https://img.shields.io/github/last-commit/phongnguyend/TrimItEasy?label=updated)](https://github.com/phongnguyend/TrimItEasy) +![GitHub Repo stars](https://img.shields.io/github/stars/phongnguyend/TrimItEasy?style=social) + +## Details + +### Info +:::info + +Name: **TrimItEasy** + +Package Description + +Author: Phong Nguyen + +NuGet: +*https://www.nuget.org/packages/TrimItEasy/* + + +You can find more details at https://github.com/phongnguyend/TrimItEasy + +Source: https://github.com/phongnguyend/TrimItEasy + +::: + +### Author +:::note +Phong Nguyen +![Alt text](https://github.com/phongnguyend.png) +::: + +## Original Readme +:::note + +# TrimItEasy + +A simple and efficient .NET library for automatically trimming string properties in complex objects. + +## Installation + +Install the package from NuGet: + +```bash +dotnet add package TrimItEasy +``` + +Or using the NuGet Package Manager in Visual Studio: +``` +Install-Package TrimItEasy +``` + +## Usage + +### Basic Usage + +Simply call the `TrimStrings()` extension method on any complex object: + +```csharp +using TrimItEasy; + +public class Person +{ + public string Name \{ get; set; } + + public string Email \{ get; set; } + + public Address HomeAddress \{ get; set; } +} + +var person = new Person +{ + Name = " John Doe ", + Email = " john@example.com ", + HomeAddress = new Address + { + Street = " 123 Main St ", + City = " New York " + } +}; + +// Trim all string properties +person.TrimStrings(); +``` + +### Skip Trimming Specific Properties + +Use the `[NotTrimmed]` attribute to prevent trimming of specific properties: + +```csharp +public class Address +{ + [NotTrimmed] + public string Street \{ get; set; \} // This property will not be trimmed + + public string City \{ get; set; \} // This property will be trimmed +} + +var address = new Address +{ + Street = " 123 Main St, Apt 4B ", // Will remain unchanged + City = " New York " // Will be trimmed to "New York" +}; + +address.TrimStrings(); +``` + +### Recursive Trimming + +By default, the library recursively trims all string properties in nested objects up to a maximum depth of 64 levels. You can customize this behavior using `TrimmingOptions`: + +```csharp +// Only trim top-level string properties (disable recursion) +person.TrimStrings(new TrimmingOptions \{ Recursive = false }); + +// Limit recursion to 2 levels of nested objects +person.TrimStrings(new TrimmingOptions \{ MaxDepth = 2 }); + +// Only trim the top-level object's string properties (no nested objects) +person.TrimStrings(new TrimmingOptions \{ MaxDepth = 0 }); +``` + +| Option | Type | Default | Description | +|-------------|--------|---------|------------------------------------------------------------------------------------------------------| +| `Recursive` | `bool` | `true` | Whether to trim strings in nested objects. When `false`, only top-level string properties are trimmed.| +| `MaxDepth` | `int` | `64` | Maximum depth for recursive trimming. `0` trims only top-level properties, `1` includes one level of nested objects, and so on. | + +### Supported Types + +The library works with: +- Complex objects with string properties +- Collections (Lists, Arrays, etc.) +- Nested objects +- Properties marked with `[NotTrimmed]` will be skipped + +### Limitations + +The library will throw an `ArgumentException` if you try to use it on: +- String types (use `string.Trim()` instead) +- Primitive types +- Enum types + +## Examples + +### Working with Collections + +```csharp +public class Company +{ + public string Name \{ get; set; } + + public List Employees \{ get; set; } +} + +public class Employee +{ + public string Name \{ get; set; } + + [NotTrimmed] + public string EmployeeId \{ get; set; } +} + +var company = new Company +{ + Name = " Acme Corp ", + Employees = new List + { + new Employee \{ Name = " John Doe ", EmployeeId = " E001 " }, + new Employee \{ Name = " Jane Smith ", EmployeeId = " E002 " } + } +}; + +company.TrimStrings(); +// Result: +// - company.Name = "Acme Corp" +// - company.Employees[0].Name = "John Doe" +// - company.Employees[0].EmployeeId = " E001 " (not trimmed due to [NotTrimmed]) +``` + +### Working with Nested Objects + +```csharp +public class Order +{ + public string OrderNumber \{ get; set; } + + public Customer Customer \{ get; set; } + + public List Items \{ get; set; } +} + +public class Customer +{ + public string Name \{ get; set; } + + [NotTrimmed] + public string PhoneNumber \{ get; set; } +} + +var order = new Order +{ + OrderNumber = " ORD-001 ", + Customer = new Customer + { + Name = " John Doe ", + PhoneNumber = " +1 (555) 123-4567 " + }, + Items = new List + { + new OrderItem \{ Description = " Product A " } + } +}; + +order.TrimStrings(); +// All string properties will be trimmed except Customer.PhoneNumber +``` + +### Source Generator (Zero Reflection) + +For maximum performance, TrimItEasy includes a source generator that produces optimized trimming code at compile time � no reflection at runtime. + +#### Installation + +Install both the core library and the source generator package: + +```bash +dotnet add package TrimItEasy +dotnet add package TrimItEasy.Generators +``` + +Or using the NuGet Package Manager in Visual Studio: +``` +Install-Package TrimItEasy +Install-Package TrimItEasy.Generators +``` + +> **Note:** The `TrimItEasy.Generators` package must be referenced as an analyzer. If you are referencing the project directly, use: +> ```xml +> OutputItemType="Analyzer" +> ReferenceOutputAssembly="false" /> +> ``` + +#### Usage + +1. **Define a `static partial` extension method** that takes your target type as a `this` parameter and returns `void`. +2. **Annotate it with `[GeneratedTrimming]`**. + +The source generator will implement the method body automatically. + +```csharp +using TrimItEasy; + +public class Person +{ + public string Name \{ get; set; } + public string Email \{ get; set; } + public Address HomeAddress \{ get; set; } + public List Phones \{ get; set; } +} + +public class Address +{ + public string Street \{ get; set; } + public string City \{ get; set; } +} + +public class Phone +{ + public string Type \{ get; set; } + public string Number \{ get; set; } +} + +// Define the partial method � the source generator fills in the implementation +public static partial class PersonExtensions +{ + [GeneratedTrimming] + public static partial void FastTrimStrings(this Person person); + + [GeneratedTrimming] + public static partial void FastTrimStringsWithOptions(this Person person, TrimmingOptions? options = null); +} +``` + +Then simply call the generated method: + +```csharp +var person = new Person +{ + Name = " John Doe ", + Email = " john@example.com ", + HomeAddress = new Address + { + Street = " 123 Main St ", + City = " New York " + }, + Phones = new List + { + new Phone \{ Type = " Mobile ", Number = " 123-456-7890 " } + } +}; + +person.FastTrimStrings(); +// All string properties are trimmed, including nested objects and collections +``` + +#### How It Works + +- The source generator analyzes the target type's property graph at compile time. +- It generates a dedicated trimming method that directly accesses each string property � no reflection involved. +- Nested objects and collections (`List`, arrays, etc.) are handled recursively. +- Properties marked with `[NotTrimmed]` are respected and skipped. +- Circular references are detected and handled safely using a visited set. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. + +::: + +### About +:::note + +trimming eacg string from a class properties + + +::: + +## How to use + +### Example (source csproj, source files) + + + + + +This is the CSharp Project that references **TrimItEasy** +```xml showLineNumbers {11} + + + + Exe + net10.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + true + $(BaseIntermediateOutputPath)\GX + + + + +``` + + + + + + This is the use of **TrimItEasy** in *Program.cs* + +```csharp showLineNumbers +using TrimDemo; + +Person p = new(); +p.FirstName = " Andrei "; +p.LastName = " Ignat "; +p.FastTrimStrings(); +Console.WriteLine(p.FirstName + " " + p.LastName); +``` + + + + +### Generated Files + +Those are taken from $(BaseIntermediateOutputPath)\GX + + + + +```csharp showLineNumbers +// +#nullable enable + +using System.Collections; +using System.Collections.Generic; + +namespace TrimDemo; + +public static partial class PersonExtensions +{ + public static partial void FastTrimStrings(this global::TrimDemo.Person person) + { + var visited = new HashSet(ReferenceEqualityComparer.Instance); + TrimProperties_TrimDemo_Person(person, visited); + } + + private static void TrimProperties_TrimDemo_Person(global::TrimDemo.Person obj, HashSet visited) + { + if (obj == null || !visited.Add(obj)) + { + return; + } + + if (obj.FirstName != null) + { + obj.FirstName = obj.FirstName.Trim(); + } + + if (obj.LastName != null) + { + obj.LastName = obj.LastName.Trim(); + } + + } + + private static void TrimRecursive(object? obj, HashSet visited) + { + if (obj == null || obj is string) + { + return; + } + + var type = obj.GetType(); + if (type.IsPrimitive || type.IsEnum || type == typeof(decimal) || type == typeof(System.DateTime) || type == typeof(System.DateTimeOffset)) + { + return; + } + + if (!type.IsValueType && !visited.Add(obj)) + { + return; + } + + if (obj is global::TrimDemo.Person typed_TrimDemo_Person) + { + TrimProperties_TrimDemo_Person(typed_TrimDemo_Person, visited); + return; + } + + if (obj is IList list) + { + for (int i = 0; i < list.Count; i++) + { + if (list[i] is string s) + { + list[i] = s.Trim(); + } + else + { + TrimRecursive(list[i], visited); + } + } + return; + } + + if (obj is IEnumerable enumerable) + { + foreach (var item in enumerable) + { + if (item is not string) + { + TrimRecursive(item, visited); + } + } + return; + } + } + +} + +``` + + + + +## Useful + +### Download Example (.NET C#) + +:::tip + +[Download Example project TrimItEasy ](/sources/TrimItEasy.zip) + +::: + + +### Share TrimItEasy + + + +https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy + + + diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md index 67311e430..f996a8660 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md @@ -1,7 +1,7 @@ --- sidebar_position: 30 -title: 286 RSCG list by category -description: 286 RSCG list by category +title: 287 RSCG list by category +description: 287 RSCG list by category slug: /rscg-examples --- @@ -578,7 +578,7 @@ import DocCardList from '@theme/DocCardList'; ## EnhancementClass
- Expand EnhancementClass =>examples:30 + Expand EnhancementClass =>examples:31 @@ -729,6 +729,11 @@ import DocCardList from '@theme/DocCardList'; [NLog.Extensions.ThisClass](/docs/NLog.Extensions.ThisClass) + + + +[TrimItEasy](/docs/TrimItEasy) +
@@ -2011,6 +2016,8 @@ flowchart LR; EnhancementClass--> NLog.Extensions.ThisClass((NLog.Extensions.ThisClass)) + EnhancementClass--> TrimItEasy((TrimItEasy)) + EnhancementProject--> ThisAssembly((ThisAssembly)) EnhancementProject--> RSCG_TimeBombComment((RSCG_TimeBombComment)) diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md index 3c5a30782..d3d8fbc0e 100644 --- a/v2/rscg_examples_site/docs/about.md +++ b/v2/rscg_examples_site/docs/about.md @@ -6,7 +6,7 @@ title: About ## Content You will find here code examples -of 286 Roslyn Source Code Generator (RSCG) +of 287 Roslyn Source Code Generator (RSCG) that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look. ## Are those examples ready for production? diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md index 9728d6125..c338f5100 100644 --- a/v2/rscg_examples_site/docs/indexRSCG.md +++ b/v2/rscg_examples_site/docs/indexRSCG.md @@ -7,9 +7,9 @@ slug: /List-of-RSCG import useBaseUrl from '@docusaurus/useBaseUrl'; -## 286 RSCG with examples in descending chronological order +## 287 RSCG with examples in descending chronological order -This is the list of 286 ( 16 from Microsoft) RSCG with examples +This is the list of 287 ( 16 from Microsoft) RSCG with examples [See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx) @@ -20,6 +20,7 @@ This is the list of 286 ( 16 from Microsoft) RSCG with examples | No | Name | Date | Category | | --------- | ----- | ---- | -------- | +|287| [TrimItEasy by Phong Nguyen ](/docs/TrimItEasy)|2026-08-28 => 28 August 2026 | [EnhancementClass](/docs/Categories/EnhancementClass) | |286| [SatorImaging.TDoubles by Sator Imaging ](/docs/SatorImaging.TDoubles)|2026-08-27 => 27 August 2026 | [Tests](/docs/Categories/Tests) | |285| [PropertyResolvers by Tom Biddulph ](/docs/PropertyResolvers)|2026-08-26 => 26 August 2026 | [EnhancementProject](/docs/Categories/EnhancementProject) | |284| [Pinecone.TypedPath by Nick Pinecone ](/docs/Pinecone.TypedPath)|2026-08-24 => 24 August 2026 | [FilesToCode](/docs/Categories/FilesToCode) | diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js index e97576692..756d9e805 100644 --- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js +++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js @@ -4,7 +4,7 @@ import styles from './styles.module.css'; const FeatureList = [ { -title: '286 Examples (16 from MSFT)', +title: '287 Examples (16 from MSFT)', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json index 7ba28fd85..fc7520304 100644 --- a/v2/rscg_examples_site/static/exports/RSCG.json +++ b/v2/rscg_examples_site/static/exports/RSCG.json @@ -2289,6 +2289,14 @@ "Source": "https://github.com/sator-imaging/TDoubles", "Category": "Tests", "AddedOn": "2026-08-27T00:00:00" + }, + { + "Name": "TrimItEasy", + "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy", + "NuGet": "https://www.nuget.org/packages/TrimItEasy/", + "Source": "https://github.com/phongnguyend/TrimItEasy", + "Category": "EnhancementClass", + "AddedOn": "2026-08-28T00:00:00" } ] } \ No newline at end of file diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx index 0bdeccf4b66eafda29700301d0d0b9182273abc0..38e247ca7ac79ea5776d58668f330769661da0f9 100644 GIT binary patch delta 896 zcmaD@(py>|;LXe;!oa}5!7z8TVr~F%{y$s-q1}$pE%WLby&v7~V0n}g+@9kQcl`aD6FLItdmEcWPe;9uGF@7BHTW-w)4$ml zRF?>U?XW5T)w%goy5{>YBGbJ09$2+$$0`}K_^P6BEpOpL0#1pW*P3fFa>A43;-C+LeaQu@>@$yW}xAdC9R|x P&rCM8Qe*pW0a5}0t5R5l delta 836 zcmeAzeOOW-;LXe;!oa}5!62|hKKA8q4uRc3o)RMi13!?i$k8v)FUn5J&(GGY$j#~P zKge~+K)|J5^-XNBtBY4OKi8ws{R+#ZrE@l^N^hP2e$|Tb{LRLvKP-#tUl?xg^G5TU z!ECVw22okHHrETz=51;!4eot9_tI0BlE6>$J7uz8)ECKlt-V<$!Q-EKKx5`&5ua(s zb4~dvv9itYIKBF*U1|xu?T^#gUp;*jeUNdgm;R%ILp!4tt+ZRY zlT|8;m(*LFu*@&?{w8Jc%-rM9y_B10=E_S<$+?Ij};xT)l&)DxyImz!=mo)e~+Sw^?Xtqflg zCF06c^5RnG1NEOD81~)2XSVya$tLlx%nyD}v4sgwwwO1+R++Q8HsWyJ?wgla6y5ar zDHBA3#y_$>r#^#9|o*$Bl-k2q=EY_qSo$w>yX}#UN zApa@P{pm&42g{C>FuQz#xpGX2Ik{D>b&$ H79c?Y@7pKQ From d994ced6b2898e22b807527ecc05e47a1805e0b0 Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Tue, 1 Sep 2026 22:33:12 +0300 Subject: [PATCH 2/2] zip --- v2/RSCGExamplesData/GeneratorDataRec.json | 3 +- v2/book/examples/TrimItEasy.html | 53 ++++++++++++++++++ v2/book/list.html | 6 +- v2/book/pandocHTML.yaml | 1 + v2/docFind.json | 6 ++ .../docs/RSCG-Examples/TrimItEasy.md | 34 +++++------ .../static/exports/RSCG.xlsx | Bin 14989 -> 14990 bytes .../static/sources/TrimItEasy.zip | Bin 0 -> 1218 bytes 8 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 v2/book/examples/TrimItEasy.html create mode 100644 v2/rscg_examples_site/static/sources/TrimItEasy.zip diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json index dd12eefe5..f5a56d8d8 100644 --- a/v2/RSCGExamplesData/GeneratorDataRec.json +++ b/v2/RSCGExamplesData/GeneratorDataRec.json @@ -1734,8 +1734,7 @@ "dtStart": "2026-08-27T00:00:00", "show": true } - , - { + ,{ "ID":"TrimItEasy", "Category": 5, "dtStart": "2026-08-28T00:00:00", diff --git a/v2/book/examples/TrimItEasy.html b/v2/book/examples/TrimItEasy.html new file mode 100644 index 000000000..3094a5ec2 --- /dev/null +++ b/v2/book/examples/TrimItEasy.html @@ -0,0 +1,53 @@ + +

RSCG nr 287 : TrimItEasy

+ +

Info

+Nuget : https://www.nuget.org/packages/TrimItEasy/ + +

You can find more details at : https://github.com/phongnguyend/TrimItEasy

+ +

Author :Phong Nguyen

+ +

Source: https://github.com/phongnguyend/TrimItEasy

+ +

About

+ +trimming eacg string from a class properties + +

+ How to use +

+

+ Add reference to the TrimItEasy in the csproj +

+ + +

This was for me the starting code

+ +
+ I have coded the file Program.cs +
+ +
+

And here are the generated files

+ +
+ The file generated is PersonExtensions_FastTrimStrings.g.cs +
+ + +

+ You can download the code and this page as pdf from + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy + +

+ + +

+ You can see the whole list at + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG + +

+ diff --git a/v2/book/list.html b/v2/book/list.html index 158b1c9f2..d9219e0a0 100644 --- a/v2/book/list.html +++ b/v2/book/list.html @@ -17,7 +17,7 @@

-This is the list of 286 RSCG with examples => +This is the list of 287 RSCG with examples =>

@@ -1170,6 +1170,10 @@

+ + + +
286 SatorImaging.TDoubles
287TrimItEasy
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml index ebec810a2..9cfa09947 100644 --- a/v2/book/pandocHTML.yaml +++ b/v2/book/pandocHTML.yaml @@ -300,6 +300,7 @@ input-files: - examples/Pinecone.TypedPath.html - examples/PropertyResolvers.html - examples/SatorImaging.TDoubles.html +- examples/TrimItEasy.html # or you may use input-file: with a single value # defaults: diff --git a/v2/docFind.json b/v2/docFind.json index 4f3c3ee43..15638d3e5 100644 --- a/v2/docFind.json +++ b/v2/docFind.json @@ -1714,5 +1714,11 @@ "category": "Tests", "href": "/RSCG_Examples/v2/docs/SatorImaging.TDoubles/", "body": "Incremental source generator for creating mock wrapper classes." + }, + { + "title": "TrimItEasy", + "category": "EnhancementClass", + "href": "/RSCG_Examples/v2/docs/TrimItEasy/", + "body": "Package Description" } ] \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md index 7d8e296f6..314ae2f27 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md @@ -49,11 +49,11 @@ Phong Nguyen ## Original Readme :::note -# TrimItEasy +### TrimItEasy A simple and efficient .NET library for automatically trimming string properties in complex objects. -## Installation +###### Installation Install the package from NuGet: @@ -66,9 +66,9 @@ Or using the NuGet Package Manager in Visual Studio: Install-Package TrimItEasy ``` -## Usage +###### Usage -### Basic Usage +######### Basic Usage Simply call the `TrimStrings()` extension method on any complex object: @@ -99,7 +99,7 @@ var person = new Person person.TrimStrings(); ``` -### Skip Trimming Specific Properties +######### Skip Trimming Specific Properties Use the `[NotTrimmed]` attribute to prevent trimming of specific properties: @@ -121,7 +121,7 @@ var address = new Address address.TrimStrings(); ``` -### Recursive Trimming +######### Recursive Trimming By default, the library recursively trims all string properties in nested objects up to a maximum depth of 64 levels. You can customize this behavior using `TrimmingOptions`: @@ -141,7 +141,7 @@ person.TrimStrings(new TrimmingOptions \{ MaxDepth = 0 }); | `Recursive` | `bool` | `true` | Whether to trim strings in nested objects. When `false`, only top-level string properties are trimmed.| | `MaxDepth` | `int` | `64` | Maximum depth for recursive trimming. `0` trims only top-level properties, `1` includes one level of nested objects, and so on. | -### Supported Types +######### Supported Types The library works with: - Complex objects with string properties @@ -149,16 +149,16 @@ The library works with: - Nested objects - Properties marked with `[NotTrimmed]` will be skipped -### Limitations +######### Limitations The library will throw an `ArgumentException` if you try to use it on: - String types (use `string.Trim()` instead) - Primitive types - Enum types -## Examples +###### Examples -### Working with Collections +######### Working with Collections ```csharp public class Company @@ -193,7 +193,7 @@ company.TrimStrings(); // - company.Employees[0].EmployeeId = " E001 " (not trimmed due to [NotTrimmed]) ``` -### Working with Nested Objects +######### Working with Nested Objects ```csharp public class Order @@ -231,11 +231,11 @@ order.TrimStrings(); // All string properties will be trimmed except Customer.PhoneNumber ``` -### Source Generator (Zero Reflection) +######### Source Generator (Zero Reflection) For maximum performance, TrimItEasy includes a source generator that produces optimized trimming code at compile time � no reflection at runtime. -#### Installation +########## Installation Install both the core library and the source generator package: @@ -257,7 +257,7 @@ Install-Package TrimItEasy.Generators > ReferenceOutputAssembly="false" /> > ``` -#### Usage +########## Usage 1. **Define a `static partial` extension method** that takes your target type as a `this` parameter and returns `void`. 2. **Annotate it with `[GeneratedTrimming]`**. @@ -320,7 +320,7 @@ person.FastTrimStrings(); // All string properties are trimmed, including nested objects and collections ``` -#### How It Works +########## How It Works - The source generator analyzes the target type's property graph at compile time. - It generates a dedicated trimming method that directly accesses each string property � no reflection involved. @@ -328,11 +328,11 @@ person.FastTrimStrings(); - Properties marked with `[NotTrimmed]` are respected and skipped. - Circular references are detected and handled safely using a visited set. -## Contributing +###### Contributing Contributions are welcome! Please feel free to submit a Pull Request. -## License +###### License This project is licensed under the MIT License - see the LICENSE file for details. diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx index 38e247ca7ac79ea5776d58668f330769661da0f9..e22a771f3a21cd4791d4be8a41f4f05e948c524a 100644 GIT binary patch delta 703 zcmeAz?JE@y@MdNaVPIh3VBp`P82hXzzIyLOVfFe>DU}9p-=65dOIJ0G>@Vy`cLd(<_Lcc)O=WfqoQv!ouMQ;lhwm$G49m*M`2@BLinc6{&qys^cs zMREG1*J5iQY4W~!n)RL*sT*4k7j9<$ z==06@3gg3KVcUlVvyyksdg;1o(^VU9!FzK5spGwceN+ZEV01 zDf&rW^yB62yO@#vvGMD1MkawRoA)toHR2Eeddp#Db@=9LQ)xzl6f-k312aQ26H7xw zlN9r$$;-^-z)I35ifx>H#!RE$+wZV}fW!Kvv-56nW)=qA&AYK-Z588jS@l5S+nbhO zn75X@?}(^DXsc8wt901npSF81*2LL`&Ax21$-F1?gP&t0N5YGq`~2&I3sin9ByNt& zExa;CJ;=W0$fquEuBt^J&Qu!N`dNwEEjTUv`tcIY2u)a!>k!IjJYh zo;TDhR%Np{>)(@6FZsefL*1%>M#I~ZHxooYT&`FxI+OKH>H37-Yos+#ZL6J<@mhUy z|Fi#UU*0`d{Muns{!26c>HC0tFSnY8`DThconAIgH16wmOUbBD_x|j^Nf?DWR}$9bE+{;*3pNTX)XKXw$EPhtI|E|bIXNx z2^@>@x+WWSv{>rm(OB<$s|4KZr`c46@RoNRAz+tzbU%T+PO5?t`SQXAFEr*9G_T?y>!2FLz~|+vC13M;CGH3-&j2Z8R=VOA*+l z^~7K6(enIKc4TjC{C1p?Y3}CD`Hae#c4TXNvc<{DFJMgb!ui_}!ZL?eqdvs9C` zM1#r8&E&vJKII!-n|#(xquw^}umO+TdZmK(s;kQ;u?22Qc`5aTsmbTR!Zwu-pUHF9 zI`?1E4$GDDO=Ld#;`}gIRUC$KJpOL|F&mmGn;6-c(+kHuk;@=yZ?v@oF zxL9;=L0yN+r%rWd+u|5+&vnO71_>(tvdMIwrSsgZ)F`TaldRX;D^AO*+0LZSd{oi> zLp&+t_Q8jCJ3hC}t7r6nbi0G)QATikjziq>_iIk*2%PV2Yz{pg^*YLQY1!4_zZ_2g zW?xWUBK)<(ruhBp-|%T3BLjma3j+f$Fi{}D%gG6rGQdEcTnD5!F-<rxv4k*;V+;Fp8Qp Nlas8}*uGnU1OZq35WD~Y diff --git a/v2/rscg_examples_site/static/sources/TrimItEasy.zip b/v2/rscg_examples_site/static/sources/TrimItEasy.zip new file mode 100644 index 0000000000000000000000000000000000000000..de834650daf91cde53ca9873400e7929c13dc9d0 GIT binary patch literal 1218 zcmWIWW@Zs#U|`^2sNAF&d-n0<8IHIm=$zaT%B6YgOsVJDv)9`Vzf9`pZqS+{@}==q?w5&Qm>2@! zc35myjD2%->4(!mvuha{7=)1Q&<{v0D$dW-OD-;*;GK2YK%nhA)7`{rZ znL9JiT;=Xt^nPW5PTSAW4?#N?NM>i%9^OAkc(Li-hB%S0^A)=$PZH1Dd*}E~y_3N% zORfI5cyE;FS6RFz`LwByP*~XdYM#nV{`*WFUi3eAx%!t0;dOVQ*MGlxH@6b#<)uI@ zjNODfTBo?Ioo#9X z8ywE-ZeFqDh`yn@sK%-#4`xgcnlfwU0+wl?JY6Pz^f~XX)9AH>QPn|>eYyyvt|r^; zCv)b9&zV1Ym3Z8g$Vsmz&z!!hF=w0E1r}9>PJ@ukQb>^`33RDSqHk$7FoNWm85ksx zT?$VT$;Aal`B_tg5BeQ)5U_PVWS=9&UzPdLCv(xV334urGHfa$Z!v~%+kN(p$lCqS z4*Gu*zjKY(Nl~i*^Ru_JzpHJY|6cwf&sXCmNAfm*J+WIzGi&kmC;pFj<}2#IDy@z^ zmKDY5ah0Vs(#168;Oj|Ulb(e#2L9nn+z@PiY|dk@j2@eI@!r=SjJ&_PT%CW zfjf6*UQ6@F5S1c{O|F_LW+`2hZ`?4t+U0OD$iu+-nCSGYv**68Xo-;wG=5w4{Y%V- z1#{2jmXKtH4-70`PbOT~*s>r( zUkZ>3(~8KD$ojFRV}$;AV46Ybho@>}1F$78gaMpPNCv=60_F=)VhiwQWdo^X0YWCA LMXP{`lYs#MJ}S@u literal 0 HcmV?d00001