NetEvolve.CodeBuilder is a high-performance, memory-efficient builder for creating C# code with proper indentation and formatting. Designed specifically for code generation scenarios, it provides an intuitive API with automatic indentation management and thread-safe operations.
This package provides a powerful code building solution that simplifies the creation of well-formatted C# code through programmatic means. The main goal is to provide developers with a time-saving tool that handles the complexity of proper code formatting, indentation, and structure, with a focus on:
- Automatic indentation management for code blocks with
{
and}
characters - High-performance operations built on top of
StringBuilder
with optimized memory usage - Flexible formatting options supporting both spaces and tabs for indentation
- Conditional code generation with
AppendIf
andAppendLineIf
methods - Culture-aware formatting with
AppendFormat
methods - XML documentation support for generating properly formatted code comments
- Memory-efficient operations with support for
ReadOnlyMemory<char>
and unsafe pointer operations
- Smart handling of opening and closing braces (
{
,}
) and brackets ([
,]
) - Configurable indentation using spaces or tabs
- Thread-safe indentation operations for multi-threaded scenarios
- Built on top of
StringBuilder
for optimal memory usage - Support for pre-allocated capacity to minimize memory allocations
- Efficient string building with minimal overhead
AppendIf()
andAppendLineIf()
methods for conditional content- Clean, readable code generation logic without complex if-else blocks
AppendFormat()
methods withIFormatProvider
support- Proper handling of culture-specific formatting requirements
- Support for multiple format arguments
- Built-in methods for generating XML documentation comments
- Support for summary, param, returns, exception, and custom elements
- Proper indentation and formatting of documentation blocks
- Support for
ReadOnlyMemory<char>
for zero-allocation string operations - Unsafe pointer operations for maximum performance scenarios
- Efficient handling of character arrays and subsets
dotnet add package NetEvolve.CodeBuilder
Install-Package NetEvolve.CodeBuilder
<PackageReference Include="NetEvolve.CodeBuilder" Version="1.0.0" />
- .NET Standard 2.0/2.1:
System.Memory
package forReadOnlyMemory<T>
support - .NET 8+: No additional dependencies
- Multi-target support: .NET Standard 2.0, 2.1, .NET 8, 9, and 10
All code building functionality is available through the CSharpCodeBuilder
class in the NetEvolve.CodeBuilder
namespace.
using NetEvolve.CodeBuilder;
// Default constructor
var builder = new CSharpCodeBuilder();
// With initial capacity for better performance
var builder = new CSharpCodeBuilder(1024);
var builder = new CSharpCodeBuilder();
builder.AppendLine("public class HelloWorld")
.Append("{")
.AppendLine("public void SayHello()")
.Append("{")
.AppendLine("Console.WriteLine(\"Hello, World!\");")
.Append("}")
.Append("}");
Console.WriteLine(builder.ToString());
Output:
public class HelloWorld
{
public void SayHello()
{
Console.WriteLine("Hello, World!");
}
}
var builder = new CSharpCodeBuilder();
builder.AppendLine("namespace MyNamespace")
.Append("{")
.AppendLine("public class MyClass")
.Append("{")
.AppendLine("private int _field;")
.AppendLine()
.AppendLine("public int Property { get; set; }")
.Append("}")
.Append("}");
var builder = new CSharpCodeBuilder();
builder.UseTabs = true; // Use tabs for indentation instead of spaces
builder.AppendLine("public class TabIndentedClass")
.Append("{")
.AppendLine("public void Method() { }")
.Append("}");
var builder = new CSharpCodeBuilder();
bool includeComments = true;
bool isPublic = true;
bool isStatic = false;
builder.AppendLineIf(includeComments, "// This is a dynamically generated class")
.AppendIf(isPublic, "public ")
.AppendIf(isStatic, "static ")
.AppendLine("class MyClass")
.Append("{")
.AppendLineIf(includeComments, "// Class implementation here")
.Append("}");
var builder = new CSharpCodeBuilder();
// Basic formatting
builder.AppendFormat(CultureInfo.InvariantCulture, "public {0} {1}", "class", "MyClass");
// Multiple arguments with proper formatting
builder.AppendFormat(CultureInfo.InvariantCulture,
"public {0} {1}({2} {3})",
"void", "SetValue", "string", "value");
// Culture-specific formatting
var culture = new CultureInfo("de-DE");
builder.AppendFormat(culture, "// Price: {0:C}", 123.45m);
var builder = new CSharpCodeBuilder();
builder.AppendXmlDocSummary("Calculates the sum of two numbers.")
.AppendXmlDocParam("a", "The first number to add.")
.AppendXmlDocParam("b", "The second number to add.")
.AppendXmlDocReturns("The sum of the two numbers.")
.AppendLine("public int Add(int a, int b)")
.Append("{")
.AppendLine("return a + b;")
.Append("}");
Output:
/// <summary>
/// Calculates the sum of two numbers.
/// </summary>
/// <param name="a">The first number to add.</param>
/// <param name="b">The second number to add.</param>
/// <returns>The sum of the two numbers.</returns>
public int Add(int a, int b)
{
return a + b;
}
var builder = new CSharpCodeBuilder();
// Using ReadOnlyMemory<char>
ReadOnlyMemory<char> methodName = "GetValue".AsMemory();
builder.AppendLine("public string ")
.Append(methodName)
.AppendLine("()");
// Pre-allocating capacity
var largeBuilder = new CSharpCodeBuilder(4096); // Pre-allocate 4KB
var builder = new CSharpCodeBuilder();
// Check current capacity and length
Console.WriteLine($"Capacity: {builder.Capacity}, Length: {builder.Length}");
// Ensure minimum capacity for performance
builder.EnsureCapacity(2048);
// Clear content while keeping capacity
builder.Clear();
public string GenerateClass(string className, List<Property> properties)
{
var builder = new CSharpCodeBuilder();
builder.AppendLine("using System;")
.AppendLine()
.AppendXmlDocSummary($"Represents a {className} entity.")
.AppendFormat(CultureInfo.InvariantCulture, "public class {0}", className)
.AppendLine()
.Append("{");
foreach (var property in properties)
{
builder.AppendXmlDocSummary($"Gets or sets the {property.Name}.")
.AppendFormat(CultureInfo.InvariantCulture,
"public {0} {1} {{ get; set; }}",
property.Type, property.Name)
.AppendLine()
.AppendLine();
}
builder.Append("}");
return builder.ToString();
}
public string GenerateMethod(string methodName, bool isAsync, bool isPublic, List<Parameter> parameters)
{
var builder = new CSharpCodeBuilder();
builder.AppendXmlDocSummary($"Executes the {methodName} operation.")
.AppendIf(isPublic, "public ")
.AppendIf(isAsync, "async Task")
.AppendIf(!isAsync, "void")
.Append($" {methodName}(");
for (int i = 0; i < parameters.Count; i++)
{
var param = parameters[i];
builder.Append($"{param.Type} {param.Name}");
if (i < parameters.Count - 1)
builder.Append(", ");
}
builder.AppendLine(")")
.Append("{")
.AppendLineIf(isAsync, "await Task.CompletedTask;")
.AppendLine("// Implementation here")
.Append("}");
return builder.ToString();
}
public string GenerateInterface(string interfaceName, List<MethodSignature> methods)
{
var builder = new CSharpCodeBuilder();
builder.AppendXmlDocSummary($"Defines the contract for {interfaceName}.")
.AppendFormat(CultureInfo.InvariantCulture, "public interface {0}", interfaceName)
.AppendLine()
.Append("{");
foreach (var method in methods)
{
builder.AppendXmlDocSummary(method.Description);
foreach (var param in method.Parameters)
{
builder.AppendXmlDocParam(param.Name, param.Description);
}
if (!string.IsNullOrEmpty(method.ReturnDescription))
{
builder.AppendXmlDocReturns(method.ReturnDescription);
}
builder.AppendFormat(CultureInfo.InvariantCulture,
"{0} {1}({2});",
method.ReturnType,
method.Name,
string.Join(", ", method.Parameters.Select(p => $"{p.Type} {p.Name}")))
.AppendLine()
.AppendLine();
}
builder.Append("}");
return builder.ToString();
}
Method | Description |
---|---|
Append(string) |
Appends a string to the builder |
Append(string, int, int) |
Appends a substring starting at specified index with specified count |
Append(bool) |
Appends the string representation of a Boolean value |
Append(char) |
Appends a character to the builder |
Append(char, int) |
Appends a character repeated the specified number of times |
Append(char[]) |
Appends a character array to the builder |
Append(char[], int, int) |
Appends a subset of a character array |
Append(ReadOnlyMemory<char>) |
Appends read-only memory of characters |
Append(ReadOnlyMemory<char>, int, int) |
Appends subset of read-only memory |
Append(char*, int) |
Appends characters from unsafe pointer (unsafe context required) |
AppendLine() |
Appends a line terminator |
AppendLine(string) |
Appends a string followed by a line terminator |
AppendLine(bool) |
Appends a Boolean value followed by a line terminator |
AppendLine(char) |
Appends a character followed by a line terminator |
AppendLine(char, int) |
Appends a repeated character followed by a line terminator |
AppendLine(char[]) |
Appends a character array followed by a line terminator |
AppendLine(char[], int, int) |
Appends a subset of character array followed by a line terminator |
AppendLine(ReadOnlyMemory<char>) |
Appends read-only memory followed by a line terminator |
AppendLine(ReadOnlyMemory<char>, int, int) |
Appends subset of read-only memory followed by a line terminator |
AppendLine(char*, int) |
Appends unsafe pointer characters followed by a line terminator |
Clear() |
Removes all content from the builder |
EnsureCapacity(int) |
Ensures the builder has at least the specified capacity |
ToString() |
Returns the built string |
Property | Type | Description |
---|---|---|
Capacity |
int |
Gets the current capacity of the internal StringBuilder |
Length |
int |
Gets the current length of the content |
UseTabs |
bool |
Gets or sets whether to use tabs instead of spaces for indentation |
Method | Description |
---|---|
AppendIf(bool, string) |
Conditionally appends a string |
AppendIf(bool, string, int, int) |
Conditionally appends a substring |
AppendIf(bool, bool) |
Conditionally appends a Boolean value |
AppendIf(bool, char) |
Conditionally appends a character |
AppendIf(bool, char, int) |
Conditionally appends a repeated character |
AppendIf(bool, char[]) |
Conditionally appends a character array |
AppendIf(bool, char[], int, int) |
Conditionally appends a subset of character array |
AppendIf(bool, ReadOnlyMemory<char>) |
Conditionally appends read-only memory |
AppendIf(bool, ReadOnlyMemory<char>, int, int) |
Conditionally appends subset of read-only memory |
AppendIf(bool, char*, int) |
Conditionally appends unsafe pointer characters |
AppendLineIf(bool) |
Conditionally appends a line terminator |
AppendLineIf(bool, string) |
Conditionally appends a string with line terminator |
AppendLineIf(bool, bool) |
Conditionally appends a Boolean value with line terminator |
AppendLineIf(bool, char) |
Conditionally appends a character with line terminator |
AppendLineIf(bool, char, int) |
Conditionally appends a repeated character with line terminator |
AppendLineIf(bool, char[]) |
Conditionally appends a character array with line terminator |
AppendLineIf(bool, char[], int, int) |
Conditionally appends a subset of character array with line terminator |
AppendLineIf(bool, ReadOnlyMemory<char>) |
Conditionally appends read-only memory with line terminator |
AppendLineIf(bool, ReadOnlyMemory<char>, int, int) |
Conditionally appends subset of read-only memory with line terminator |
AppendLineIf(bool, char*, int) |
Conditionally appends unsafe pointer characters with line terminator |
Method | Description |
---|---|
AppendFormat(string, object) |
Appends formatted string with single argument |
AppendFormat(string, params object[]) |
Appends formatted string with multiple arguments |
AppendFormat(IFormatProvider, string, object) |
Appends formatted string with single argument and format provider |
AppendFormat(IFormatProvider, string, object, object) |
Appends formatted string with two arguments and format provider |
AppendFormat(IFormatProvider, string, object, object, object) |
Appends formatted string with three arguments and format provider |
AppendFormat(IFormatProvider, string, params object[]) |
Appends formatted string with multiple arguments and format provider |
Method | Description |
---|---|
AppendXmlDoc(string) |
Appends a single-line XML documentation comment |
AppendXmlDocSummary(string) |
Appends an XML summary element |
AppendXmlDocSummary(IEnumerable<string>) |
Appends an XML summary element with multiple lines |
AppendXmlDocParam(string, string) |
Appends an XML param element |
AppendXmlDocParams(IEnumerable<(string, string)>) |
Appends multiple XML param elements |
AppendXmlDocReturns(string) |
Appends an XML returns element |
AppendXmlDocException(string, string) |
Appends an XML exception element |
AppendXmlDocExceptions(IEnumerable<(string, string)>) |
Appends multiple XML exception elements |
AppendXmlDocRemarks(string) |
Appends an XML remarks element |
AppendXmlDocRemarks(IEnumerable<string>) |
Appends an XML remarks element with multiple lines |
AppendXmlDocExample(string) |
Appends an XML example element |
AppendXmlDocExample(IEnumerable<string>) |
Appends an XML example element with multiple lines |
AppendXmlDocValue(string) |
Appends an XML value element |
AppendXmlDocTypeParam(string, string) |
Appends an XML typeparam element |
AppendXmlDocTypeParams(IEnumerable<(string, string)>) |
Appends multiple XML typeparam elements |
AppendXmlDocSee(string) |
Appends an XML see element |
AppendXmlDocSeeAlso(string) |
Appends an XML seealso element |
AppendXmlDocInheritDoc(string) |
Appends an XML inheritdoc element |
AppendXmlDocCustomElement(string, string, string) |
Appends a custom XML documentation element |
Note: Indentation is handled automatically when appending {
}
[
]
characters. Manual indentation control methods are internal to the library and not directly accessible.
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
This package is part of the NetEvolve ecosystem of .NET extensions and utilities. Check out other packages in the NetEvolve family for additional functionality.
Made with β€οΈ by the NetEvolve Team