Reach expert-level proficiency by mastering tools, profiling, metaprogramming, and the broader C# ecosystem.
In this chapter, we'll explore how to optimize performance and manage memory effectively in C#. We'll cover essential tools like BenchmarkDotNet
for identifying bottlenecks, and dive deep into concepts such as garbage collection, memory pressure, and the use of Span<T> and Memory<T>.
BenchmarkDotNet
results, not assumptions.// Example: Using BenchmarkDotNet
using BenchmarkDotNet.Attributes;
[MemoryDiagnoser]
public class MyBenchmarks
{
[Benchmark]
public void MyMethod()
{
// Code to benchmark
}
}
GC.Collect()
judiciously and only in specific scenarios where manual control is needed.Span<T> and Memory<T> are powerful tools for working with memory in a safe and efficient way. They allow you to work directly with memory without allocations, improving performance significantly.
// Example: Using Span<T>
Span<int> span = stackalloc int[10];
for (int i = 0; i < span.Length; i++)
{
span[i] = i;
}
// Example: Using Memory<T>
Memory<int> memory = new int[10];
memory.Span.Fill(42);
BenchmarkDotNet
to identify performance bottlenecks.GC.Collect()
as it can harm performance.// Example: Avoiding unnecessary allocations
List<int> numbers = new List<int>();
for (int i = 0; i < 1000; i++)
{
numbers.Add(i);
}
// Better approach using Memory<T>
Memory<int> numbers = Memory<int>.Empty;
numbers = GC.AllocateArray<int>(1000);
for (int i = 0; i < numbers.Length; i++)
{
numbers.Span[i] = i;
}
Welcome to Source Generators and Reflection in C#! In this chapter, you'll learn how to leverage the power of the Roslyn compiler to generate code at compile-time using Source Generators, and how to inspect and manipulate types at runtime using Reflection. These tools are essential for building flexible, maintainable applications.
A Source Generator is a component that runs during compilation and generates additional C# code based on specific rules or templates. This enables you to automate repetitive tasks, reduce boilerplate code, and create highly maintainable applications.
using Microsoft.CodeAnalysis;
[Generator]
public class MySourceGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
// Configuration logic here
}
public void Execute(GeneratorExecutionContext context)
{
// Logic to generate code
}
}
.csproj
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
</ItemGroup>
Reflection is a powerful feature that allows you to inspect and manipulate types, methods, properties, and other elements of your application at runtime. It provides flexibility for scenarios where traditional compile-time checks aren't sufficient.
Type type = typeof(MyClass);
Console.WriteLine(type.Name); // Outputs "MyClass"
Type myType = typeof(MyClass);
foreach (MethodInfo method in myType.GetMethods())
{
Console.WriteLine($"Method: {method.Name}");
}
Welcome to Working with NuGet, .NET CLI, and Build Pipelines! This chapter will guide you through essential practices for package management, automation, and continuous integration in C# development.
NuGet is the package manager for .NET projects. It allows you to easily incorporate libraries and tools into your applications.
dotnet add package Newtonsoft.Json
// Install a popular JSON handling library
dotnet add package <package>
- Install a packagedotnet list package
- View installed packagesdotnet remove package <package>
- Uninstall a packageThe .NET CLI provides powerful tools for building, testing, and deploying applications from the command line.
# Build a project
$ dotnet build
# Run tests
$ dotnet test
# Publish an application
$ dotnet publish
Integrate your .NET projects into a continuous integration and delivery workflow using GitHub Actions.
.github/workflows/ci-cd.yml
name: Build & Deploy
on:
push:
branches: [ main ]
jobs:
build:
runs-on: windows-latest
steps:
- checkout: self
- uses: actions/checkout@v3
- name: Restore packages
run: dotnet restore
- name: Build project
run: dotnet build --configuration Release
Question 1 of 15