« Csharp 8 » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
(Page créée avec « Category:CSharp = Liens = * [https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8 What's new in C# 8.0] ») |
|||
(28 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 2 : | Ligne 2 : | ||
= Liens = | = Liens = | ||
* [https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8 What's new in C# 8.0] | * [https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8 What's new in C# 8.0] | ||
* [https://docs.microsoft.com/en-gb/dotnet/csharp/language-reference/configure-language-version C# language versioning] | |||
= [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression Switch expression] = | |||
<kode lang='cs'> | |||
string myVar; | |||
switch (i) | |||
{ | |||
case 1: | |||
myVar = "One"; | |||
break; | |||
case 2: | |||
case 3: | |||
myVar = "Two-Three"; | |||
break; | |||
case var x when x > 0 && x < 10: | |||
myVar = "Zero-Ten"; | |||
break; | |||
default: | |||
throw new ArgumentOutOfRangeException(nameof(i), i); | |||
} | |||
var myVar = i switch | |||
{ | |||
1 => "One", | |||
2 or 3 => "Two-Three", | |||
> 0 and < 10 => "Zero-Ten", | |||
_ => throw new ArgumentOutOfRangeException(nameof(i), i) | |||
}; | |||
</kode> | |||
= Using declaration = | |||
<kode lang='cs'> | |||
using (var file = new StreamWriter("MyFile.txt")) | |||
{ | |||
// some code | |||
} // file is disposed here | |||
void MyMethod() | |||
{ | |||
using var file = new StreamWriter("MyFile.txt"); | |||
// some code | |||
// file is disposed here, at the end of the enclosing scope | |||
} | |||
</kode> | |||
= Static local function = | |||
<kode lang='cs'> | |||
int x = 5; | |||
int y = 7; | |||
return Add(x, y); | |||
// Can be static because it doesn't access any variables in the enclosing scope | |||
static int Add(int left, int right) => left + right; | |||
</kode> | |||
= [https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/generate-consume-asynchronous-stream Asynchronous streams / async yield] = | |||
<kode lang='cs'> | |||
public static async IAsyncEnumerable<int> GenerateSequence() | |||
{ | |||
for (int i = 0; i < 20; i++) | |||
{ | |||
await Task.Delay(100); | |||
yield return i; | |||
} | |||
} | |||
await foreach (var number in GenerateSequence()) | |||
{ | |||
Console.WriteLine(number); | |||
} | |||
</kode> | |||
= Indices and ranges = | |||
<kode lang='cs'> | |||
var latest = myList[^1]; | |||
var secondToFour = myList[2..5]; | |||
var lastTwo = myList[^2..^0]; | |||
var firstThree = myList[..4]; | |||
var allExceptFirst = myList[2..]; | |||
</kode> | |||
= Null-coalescing assignment / ?? <nowiki>=</nowiki> = | |||
<kode lang='cs'> | |||
int? i = null; | |||
i = i == null ? 20 : i; | |||
i = i ?? 20; | |||
i ??= 20; // assign 20 to i if i is null | |||
</kode> | |||
= [https://www.meziantou.net/csharp-8-nullable-reference-types.htm Nullable reference type] = | |||
<filebox fn='MyProject.csproj' lang='xml'> | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp3.1</TargetFramework> | |||
<!-- add this line to enable it --> | |||
<Nullable>enable</Nullable> | |||
</filebox> | |||
Now by default everything is non nullable. If you want to declare a type as accepting null values, you need to add {{boxx|?}} after the type. | |||
<kode lang='cs'> | |||
string s1 = null; // Warning: Converting null literal or possible null value to non-nullable type. | |||
string? s2 = null; // ok | |||
// null-forgiving operator | |||
Console.WriteLine(s2!.Length); // in this case we know that s2 is not null, so we can use "!" to instruct the compiler "s2" is not null here | |||
// allow null even if the type is not nullable | |||
public void MyMethod([AllowNull]ref string value) | |||
{ } | |||
// disallow null even if the type is nullable | |||
public void MyMethod([DisallowNull]ref string? value) | |||
{ } | |||
private string s1 = ""; | |||
// allow null for setter even if the type is not nullable | |||
[AllowNull] | |||
public string S1 | |||
{ | |||
get => s1; | |||
set => s1 = value ?? ""; | |||
} | |||
</kode> | |||
= [https://stackoverflow.com/questions/56651472/does-c-sharp-8-support-the-net-framework .NET Framework] = | |||
The {{boxx|C# 8}} / {{boxx|.NET Framework}} combination is not officially supported by Microsoft.<br> | |||
It can be forced by editing the csproj file. | |||
<filebox fn='MyProject.csproj' lang='xml'> | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<PropertyGroup> | |||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | |||
<LangVersion>8.0</LangVersion> | |||
</filebox> | |||
* {{boxx|default interface members}} won't work | |||
* {{boxx|asynchronous streams}} and {{boxx|indices and ranges}} will need {{boxx|polyfill}} nuget package |
Dernière version du 20 octobre 2024 à 12:57
Liens
Switch expression
string myVar; switch (i) { case 1: myVar = "One"; break; case 2: case 3: myVar = "Two-Three"; break; case var x when x > 0 && x < 10: myVar = "Zero-Ten"; break; default: throw new ArgumentOutOfRangeException(nameof(i), i); } var myVar = i switch { 1 => "One", 2 or 3 => "Two-Three", > 0 and < 10 => "Zero-Ten", _ => throw new ArgumentOutOfRangeException(nameof(i), i) }; |
Using declaration
using (var file = new StreamWriter("MyFile.txt")) { // some code } // file is disposed here void MyMethod() { using var file = new StreamWriter("MyFile.txt"); // some code // file is disposed here, at the end of the enclosing scope } |
Static local function
int x = 5; int y = 7; return Add(x, y); // Can be static because it doesn't access any variables in the enclosing scope static int Add(int left, int right) => left + right; |
Asynchronous streams / async yield
public static async IAsyncEnumerable<int> GenerateSequence() { for (int i = 0; i < 20; i++) { await Task.Delay(100); yield return i; } } await foreach (var number in GenerateSequence()) { Console.WriteLine(number); } |
Indices and ranges
var latest = myList[^1]; var secondToFour = myList[2..5]; var lastTwo = myList[^2..^0]; var firstThree = myList[..4]; var allExceptFirst = myList[2..]; |
Null-coalescing assignment / ?? =
int? i = null; i = i == null ? 20 : i; i = i ?? 20; i ??= 20; // assign 20 to i if i is null |
Nullable reference type
MyProject.csproj |
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <!-- add this line to enable it --> <Nullable>enable</Nullable> |
Now by default everything is non nullable. If you want to declare a type as accepting null values, you need to add ? after the type.
string s1 = null; // Warning: Converting null literal or possible null value to non-nullable type. string? s2 = null; // ok // null-forgiving operator Console.WriteLine(s2!.Length); // in this case we know that s2 is not null, so we can use "!" to instruct the compiler "s2" is not null here // allow null even if the type is not nullable public void MyMethod([AllowNull]ref string value) { } // disallow null even if the type is nullable public void MyMethod([DisallowNull]ref string? value) { } private string s1 = ""; // allow null for setter even if the type is not nullable [AllowNull] public string S1 { get => s1; set => s1 = value ?? ""; } |
.NET Framework
The C# 8 / .NET Framework combination is not officially supported by Microsoft.
It can be forced by editing the csproj file.
MyProject.csproj |
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <LangVersion>8.0</LangVersion> |
- default interface members won't work
- asynchronous streams and indices and ranges will need polyfill nuget package