Auto-Implemented Properties
Property declarations can be simplified when no extra logic is required in the accessors. Instead of writing a full backing field, use auto-implemented properties:
public string Label { get; set; }
var entry = new SomeRecord();
entry.Label = "Example";
Console.WriteLine(entry.Label);
Anonymous Types for Local Projections
When you need a temoprary shape for data, anonymous types avoid formal class definitions:
var item = new { Title = "Widget", Weight = 5.2 };
Console.WriteLine(item.Title);
Console.WriteLine(item.Weight);
Adding Capabilities with Extension Methods
Extend existing types without inheritance by defining static methods in a static class, using the this modifier on the first parameter:
public static class TextHelpers
{
public static bool IsBlank(this string source) =>
string.IsNullOrWhiteSpace(source);
}
string test = " ";
bool check = test.IsBlank(); // true
Default Parameter Values
Methods can supply fallback values for arguments, reducing overloads:
static void ShowDetails(string id, int count = 1, bool verbose = false)
{
Console.WriteLine($"{id} count={count} verbose={verbose}");
}
ShowDetails("X44");
ShowDetails("Y99", verbose: true);
Dynamic Binding for Flexible Invocation
The dynamic keyword defers type resolution to runtime, enabling duck typing scenarios:
dynamic obj = "hello world";
Console.WriteLine(obj.GetType()); // System.String
Console.WriteLine(obj.ToUpperInvariant()); // HELLO WORLD
Asynchronous Execution with async/await
Writing responsive, non-blocking code becomes straightforward with async and await. The compiler handles continuation management.
async Task<int> ComputeSumAsync()
{
await Task.Delay(800);
return 10 + 25;
}
int total = await ComputeSumAsync();
Console.WriteLine(total);