New features in C# 8 including nullable reference types, async streams, switch expressions, ranges, default interface members, enhanced pattern matching
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
C# 8 in Libraries and Applications
1. C# 8 in Libraries and
Applications
Christian Nagel
https://csharp.christiannagel.com
2. Topics
NEW C# 8 FEATURES HOW TO USE C# 8 IN
LIBRARIES AND
APPLICATIONS
GUIDELINES
3. Christian Nagel
• Training
• Coaching
• Consulting
• Development
• Microsoft MVP
• www.cninnovation.com
• csharp.christiannagel.com
• github.com/cninnovation
5. How to use C# 8
• By default enabled with
.NET Core 3.0
• Enable with other projects
• <LangVersion>8.0</LangVersion>
• <Nullable>enable</Nullable>
• Directory.Build.Props
6. Features based on
Frameworks/Runtimes
• Syntax Sugar Features mit allen Frameworks
• Manche Features brauchen Klassen &
Interfaces
• Ranges, async streams
• Runtime Updates Required
• .NET Standard 2.1
• Default Interface Members
16. Range
string text1 = "the quick brown fox jumped over the lazy dogs";
string quick = text1[4..9];
string dog = text1[^4..^1];
string brownfoxjumpedandmore = text1[10..];
string thequick = text1[..8];
string text2 = text1[..];
17. Demo
• Ranges and Indices
• Access Slice of Span<T>
• Access String
• Range, Index Types
• Custom Collections
26. Guidelines
• Library authors – Nullable adoption phase before
.NET 5
• App developers – nullability on your own pace
• Annotate new APIs
• Do not remove argument validation
• Parameter is non-nullable if parameters are
checked (ArgumentNullException)
• Parameter is nullable if documented to accept null
• Prefer nullable over non-nullable with
disagreements
28. Async
Streams
bis jetzt: async/await liefert ein Ergebnis
Async Streams erweitert async/await mit
Stream von Ergebnissen
Asynchronous Datenquellen die vom
Consumer kontrolliert werden
Alternative zu System.Reactive
29. Async Streams
• IAsyncDisposable
• IAsyncEnumerable
• IAsyncEnumerator
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator();
}
public interface IAsyncEnumerator<out T> :
IAsyncDisposable
{
ValueTask<bool> MoveNextAsync();
T Current { get; }
}
30. Using Async Streams
• await foreach
IAsyncEnumerator<T> enumerator =
enumerable.GetAsyncEnumerator();
try
{
while (await enumerator.MoveNextAsync())
{
Use(enumerator.Current);
}
}
finally
{
await enumerator.DisposeAsync();
}
await foreach (var i in enumerable)
{
Use(i);
}
31. Async with yield
• return IAsyncEnumerable static async IAsyncEnumerable<int> MyIterator()
{
try
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(1000);
yield return i;
}
}
finally
{
await Task.Delay(200);
Console.WriteLine("finally");
}
}
32. Demo
• Async Streams & SignalR
• Streaming from the Server to the
Client
• Streaming from the Client to the
Server
• C# 8 Async Streams
34. using declaration
public void Method(IEnumerable<string> lines)
{
using var file = new StreamWriter("sample.txt");
foreach (var line in lines)
{
file.WriteLine(line);
}
}
35. switch Expression
static string M2(Shape shape) =>
shape switch
{
Shape s when s.Size.height > 100 =>
$"large shape with size {s.Size} at position {s.Position}",
Ellipse e =>
$"Ellipse with size {e.Size} at position {e.Position}",
Rectangle r =>
$"Rectangle with size {r.Size} at position {r.Position}",
_ => "another shape"
}
};
36. Recursive, Property, and Discard Patterns
static string M3(Shape shape) =>
shape switch
{
CombinedShape (var shape1, var (pos, _)) =>
$"combined shape - shape1: {shape1.Name}, pos of shape2: {pos}",
{ Size: (200, 200), Position: var pos } =>
$"shape with size 200x200 at position {pos.x}:{pos.y}",
Ellipse (var pos, var size) =>
$"Ellipse with size {size} at position {pos}",
Rectangle (_, var size) => $"Rectangle with size {size}",
_ => "another shape"
};
40. For action
• Annotate libraries with nullability
• Use new C# 8 features
• https://csharp.christiannagel.com
• https://github.com/cninnovation
• https://github.com/ProfessionalCSharp