← Back to Tutorials Chapter 13

Advanced Topics

This chapter explores advanced .NET Core features for performance optimization, extensibility, interop with native code, diagnostics, reflection, and source generators.

Performance Optimization

Modern .NET provides several high-performance APIs that minimize allocations and improve throughput.

Span<T> and Memory<T>

Span<T> is a stack-allocated, ref-like type that provides safe access to contiguous memory without allocations. Memory<T> is its heap-compatible counterpart.

Span<byte> buffer = stackalloc byte[256];
ReadOnlySpan<char> text = "Hello".AsSpan();
int vowels = text.Count(SpanExtensions.IsVowel);

// Slicing without allocation
Span<byte> slice = buffer.Slice(10, 20);

ref struct

A ref struct is a value type that lives only on the stack. It cannot be boxed or used as a field of a class.

public ref struct Matrix3x3
{
    public float M11, M12, M13;
    public float M21, M22, M23;
    public float M31, M32, M33;
}

BenchmarkDotNet

BenchmarkDotNet is the gold standard for microbenchmarking in .NET:

[MemoryDiagnoser]
public class StringBenchmarks
{
    [Benchmark]
    public string Concat() => string.Concat("a", "b", "c");

    [Benchmark]
    public string Interpolation() => $"{'a'}{'b'}{'c'}";
}

Extensibility

Managed Extensibility Framework (MEF) provides a plug-in architecture:

[Export(typeof(IPlugin))]
public class MyPlugin : IPlugin { }

// Composition
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
var plugins = container.GetExports<IPlugin>();

Custom MSBuild tasks let you extend the build pipeline:

public class MyTask : Microsoft.Build.Utilities.Task
{
    public override bool Execute()
    {
        Log.LogMessage("Custom task running...");
        return true;
    }
}

Interop

P/Invoke calls native C functions:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

COM Interop allows consuming COM objects. Generate interop assemblies with tlbimp.exe or use dynamic with System.Runtime.InteropServices.

.NET Core advanced concepts

Diagnostics

.NET Core includes powerful diagnostic tools:

dotnet tool install -g dotnet-counters
dotnet tool install -g dotnet-dump
dotnet tool install -g dotnet-trace

dotnet-counters monitor --process-id 1234
dotnet-dump collect --process-id 1234
dotnet-trace collect --providers Microsoft-DotNETCore-SampleProfiler

Use these tools to monitor CPU, memory, garbage collection, and thread pool metrics in production.

Reflection

Reflection enables inspecting types, invoking members, and creating instances at runtime:

Assembly asm = Assembly.LoadFrom("MyLibrary.dll");
Type type = asm.GetType("MyLibrary.MyClass");
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("MyMethod");
method.Invoke(obj, new object[] { "arg" });

// Custom attributes
[AttributeUsage(AttributeTargets.Class)]
public class DisplayNameAttribute : Attribute
{
    public string Name { get; }
    public DisplayNameAttribute(string name) => Name = name;
}

Source Generators

Source generators produce C# source files during compilation. They enable compile-time code generation without reflection overhead.

[Generator]
public class HelloGenerator : ISourceGenerator
{
    public void Execute(GeneratorExecutionContext context)
    {
        var source = "namespace Gen { public class Hello { public static string World() => \"Hello\"; } }";
        context.AddSource("Hello.g.cs", source);
    }

    public void Initialize(GeneratorInitializationContext context) { }
}
Source generators are commonly used for auto-generating serialization code, dependency injection registrations, and mapper implementations.
Exercise: Write a source generator that scans all classes in the compilation marked with [AutoLog] and generates a partial class with an ILogger property and a LogMethodEntry/Exit helper. Then use BenchmarkDotNet to compare the performance of string.Concat vs StringBuilder for 100 concatenations.