Master high-performance patterns: Span/Memory for zero-allocation code, source generators, and async channels.
Write high-performance, modern C# with cutting-edge features.
Span<T> and Memory<T> for high-performance, zero-allocation operations on contiguous memory.int[] numbers = { 1, 2, 3, 4, 5 };
Span<int> span = numbers.AsSpan();
// or: Span<int> span = new Span<int>(numbers);
2. Slice without allocation:
Span<int> slice = span.Slice(1, 3); // [2, 3, 4]
// Modifications affect original array!
slice[0] = 99; // numbers[1] is now 99
3. Use ReadOnlySpan for strings:
ReadOnlySpan<char> text = "Hello, World!".AsSpan();
ReadOnlySpan<char> hello = text.Slice(0, 5); // "Hello"
4. Parse without allocation:
ReadOnlySpan<char> numStr = "12345".AsSpan();
int parsed = int.Parse(numStr);
5. Use Memory<T> for async scenarios:
Memory<int> mem = numbers.AsMemory();
// Memory can be stored in fields, passed to async methods.Span property to get Span from MemoryOriginal: 1, 2, 3, 4, 5
Slice [1..4]: 2, 3, 4
After modification: 1, 99, 3, 4, 5
String slice: Hello
Parsed number: 12345
Span<int> s = array.AsSpan();span.Slice(start, length) or span[1..4]ReadOnlySpan<char> = "text".AsSpan();Memory<int> m = array.AsMemory();Review feedback below
[AutoNotify] // Attribute marks class for generation
public partial class Person
{
private string _name;
private int _age;
}
2. Generated code adds functionality:
// Generated partial class
public partial class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
}
3. Simulate a ToString generator:
[GenerateToString]
public partial class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
// Generated: public override string ToString() => $"Product {{ Id = {Id}, Name = {Name} }}";
4. Use partial methods:
partial class MyClass
{
partial void OnCreated(); // Declaration
}
partial class MyClass
{
partial void OnCreated() { Console.WriteLine("Created!"); } // Implementation
}Person: Alice, Age: 30
PropertyChanged fired for: Name
Product: Product { Id = 1, Name = Widget }
OnCreated was called!
[AttributeUsage(AttributeTargets.Class)]public partial class Name { }PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));partial void MethodName();Review feedback below
Channel<T> for high-performance async producer-consumer patterns.var channel = Channel.CreateBounded<int>(new BoundedChannelOptions(10)
{
FullMode = BoundedChannelFullMode.Wait
});
2. Create an unbounded channel:
var channel = Channel.CreateUnbounded<string>();
3. Write to channel (producer):
var writer = channel.Writer;
await writer.WriteAsync(42);
writer.Complete(); // Signal no more items
4. Read from channel (consumer):
var reader = channel.Reader;
await foreach (var item in reader.ReadAllAsync())
{
Console.WriteLine(item);
}
5. Multiple producers/consumers:
// Start producer task
var producer = Task.Run(async () => { ... });
// Start consumer task
var consumer = Task.Run(async () => { ... });
await Task.WhenAll(producer, consumer);Complete() when done writingReadAllAsync() returns IAsyncEnumerable<T>Producer: Writing 0
Producer: Writing 1
Consumer: Read 0
Consumer: Read 1
Producer: Writing 2
Consumer: Read 2
All done!
Channel.CreateBounded<T>(capacity)Channel.CreateUnbounded<T>()await writer.WriteAsync(item);await foreach (var x in reader.ReadAllAsync())Review feedback below