※ 2019/08/17 15:16 更新 Preview5からPreview7を追記
.NET Core 3 Previewについて公式ブログにある内容から、個人的に気になるものをまとめます。完全に備忘録。
なお .NET Core 3 Previewはこれまで4回7回リリースされています。
Preview1
Resources
- Announcing .NET Core 3 Preview 1 and Open Sourcing Windows Desktop Frameworks | .NET Blog
- core/3.0.0-preview1.md at master · dotnet/core
Overview
- .NET Framework 4.8のリリース
- Windowsデスクトップアプリケーションのサポート
- WinForms
dotnet new winforms
- WPF
dotnet new wpf
- WinForms
- Entity Framework 6のサポート
- 実行可能ファイル (
.exe
) を生成できるようになる System.Text.Json.Utf8JsonReader
- Json.NET >
JsonConvert.Deserialize
の2倍高速
- Json.NET >
- 添字の指定
Index
型^4
... 配列の後方から4番目3...^4
... 開始:配列の3番目、終了:配列の後方から5番目
- 非同期ストリーム
IAsyncEnumerable<T>
- C# 8
- IAsyncEnumerable T Interface (System.Collections.Generic) | Microsoft Docs
IEnumerable<T>
の非同期バージョンawait foreach
yield return
System.Buffers.SequenceReader
- Linuxでシリアルポートをサポート
- 暗号手法
- AES-GCM
System.Security.Cryptography.AesGcm
- AES-CCM
System.Security.Cryptography.AesCcm
- AES-GCM
- 暗号化キーのインポート/エクスポート
- Interfaceのメソッドの既定の実装
- C# 8
- インターフェースに定義されたメソッドの既定の挙動を実装できる
- 階層型コンパイル
MetadataLoadContext
とアセンブリメタデータの読み込み- MetadataLoadContext Class (System.Reflection) | Microsoft Docs
- NuGet
System.Reflection.MetadataLoadContext
- NuGet Gallery | System.Reflection.MetadataLoadContext 4.6.0-preview4.19212.13
- .NET Standard 2.0で使える
- ARM64のサポート
WPF csproj
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <UseWPF>true</UseWPF> </PropertyGroup> </Project>
<UseWPF>true</UseWPF>
WinForms csproj
<ProjectSdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <UseWindowsForms>true</UseWindowsForms> </PropertyGroup> </Project>
<UseWindowsForms>true</UseWindowsForms>
System.Text.Json.Utf8JsonReader
public static void Utf8JsonReaderLoop(ReadOnlySpan<byte> dataUtf8) { var json = new Utf8JsonReader(dataUtf8, isFinalBlock: true, state: default); while (json.Read()) { JsonTokenType tokenType = json.TokenType; ReadOnlySpan<byte> valueSpan = json.ValueSpan; switch (tokenType) { case JsonTokenType.StartObject: case JsonTokenType.EndObject: break; case JsonTokenType.StartArray: case JsonTokenType.EndArray: break; case JsonTokenType.PropertyName: break; case JsonTokenType.String: string valueString = json.GetStringValue(); break; case JsonTokenType.Number: if (!json.TryGetInt32Value(out int valueInteger)) { throw new FormatException(); } break; case JsonTokenType.True: case JsonTokenType.False: bool valueBool = json.GetBooleanValue(); break; case JsonTokenType.Null: break; default: throw new ArgumentException(); } } dataUtf8 = dataUtf8.Slice((int)json.BytesConsumed); JsonReaderState state = json.CurrentState; }
IAsyncEnumerable<T>
async IAsyncEnumerable<int> GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { if (result > 20) yield return result; } }
Interfaceのメソッドの既定の実装
interface ILogger { void Log(LogLevel level, string message); void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload } class ConsoleLogger : ILogger { public void Log(LogLevel level, string message) { ... } // Log(Exception) gets default implementation }
MetadataLoadContext
var paths = new string[] {@"C:\myapp\mscorlib.dll", @"C:\myapp\myapp.dll"}; var resolver = new PathAssemblyResolver(paths); using (var lc = new MetadataLoadContext(resolver)) { Assembly a = lc.LoadFromAssemblyName("myapp"); Type myInterface = a.GetType("MyApp.IPluginInterface"); foreach (Type t in a.GetTypes()) { if (t.IsClass && myInterface.IsAssignableFrom(t)) Console.WriteLine($"Class {t.FullName} implements IPluginInterface"); } }
Preview2
Resources
Overview
- C# 8で追加された機能
- ドキュメント
- 機能
System.Text.Json.Utf8JsonWriter
&System.Text.Json.JsonDocument
- Preview1では
System.Text.Json.Utf8JsonReader
- Preview1では
- Raspberry PiのGPIOサポート
- dotnet tools
- Assembly Unloadability
- Windows Native Interop
Switch式
単一の項目
static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point { X: var x, Y: var y } => $"({x}, {y})", _ => "unknown" };
複数の項目
static State ChangeState(State current, Transition transition, bool hasKey) => (current, transition) switch { (Opened, Close) => Closed, (Closed, Open) => Opened, (Closed, Lock) when hasKey => Locked, (Locked, Unlock) when hasKey => Closed, _ => throw new InvalidOperationException($"Invalid transition") };
System.Text.Json.Utf8JsonWriter
static int WriteJson(IBufferWriter<byte> output, long[] extraData) { var json = new Utf8JsonWriter(output, state: default); json.WriteStartObject(); json.WriteNumber("age", 15, escape: false); json.WriteString("date", DateTime.Now); json.WriteString("first", "John"); json.WriteString("last", "Smith"); json.WriteStartArray("phoneNumbers", escape: false); json.WriteStringValue("425-000-1212", escape: false); json.WriteStringValue("425-000-1213"); json.WriteEndArray(); json.WriteStartObject("address"); json.WriteString("street", "1 Microsoft Way"); json.WriteString("city", "Redmond"); json.WriteNumber("zip", 98052); json.WriteEndObject(); json.WriteStartArray("ExtraArray"); for (var i = 0; i < extraData.Length; i++) { json.WriteNumberValue(extraData[i]); } json.WriteEndArray(); json.WriteEndObject(); json.Flush(isFinalBlock: true); return (int)json.BytesWritten; }
System.Text.Json.JsonDocument
static double ParseJson() { const string json = " [ { \"name\": \"John\" }, [ \"425-000-1212\", 15 ], { \"grades\": [ 90, 80, 100, 75 ] } ]"; double average = -1; using (JsonDocument doc = JsonDocument.Parse(json)) { JsonElement root = doc.RootElement; JsonElement info = root[1]; string phoneNumber = info[0].GetString(); int age = info[1].GetInt32(); JsonElement grades = root[2].GetProperty("grades"); double sum = 0; foreach (JsonElement grade in grades.EnumerateArray()) { sum += grade.GetInt32(); } int numberOfCourses = grades.GetArrayLength(); average = sum / numberOfCourses; } return average; }
Preview3
Resources
Overview
- .NET Core 3.0のリリースは2019年後半の予定
- Buildで発表する
- .NET Core SDKをインストール時のアップグレード
- ビルド番号以下は置き換えられる
- Docker and cgroup memory Limits
- Dockerイメージの場所が変わった
- Microsoft Container Registry (MCR)
- Index and Range
- .NET Standard 2.1
- AssemblyDependencyResolver
- アセンブリの動的ロード
Index and Range
// start with int[] int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int lastNum = nums[^1]; // 10 int[] subsetNums = nums[2..6]; // {3, 4, 5, 6} // Create a Memory<int> using arrayofNums as input // Create no-copy slices of the array Memory<int> numbers = nums; Memory<int> lastTwoNums = numbers.Slice(^2); // {9, 10} Memory<int> middleNums = numbers.Slice(4..8); // {5, 6, 7, 8} // Create a substring using a range string myString = "0123456789ABCDEF"; string substring = myString[0..5]; // "01234" // Create a Memory<char> using a range ReadOnlyMemory<char> myChars = myString.AsMemory(); ReadOnlyMemory<char> firstChars = myChars[0..5]; // {'0', '1', '2', '3', '4'} // Get an offset with an Index Index indexFromEnd = Index.FromEnd(3); // equivalent to [^3] int offsetFromLength = indexFromEnd.GetOffset(10); // 7 int value = nums[offsetFromLength]; // 8 // Get an offset with a Range Range rangeFromEnd = 5..^0; (int offset, int length) = rangeFromEnd.GetOffsetAndLength(10); // offset = 5, length = 5 Memory<int> values = numbers.Slice(offset, length); // {6, 7, 8, 9, 10}
.NET Standard 2.1
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> </PropertyGroup> </Project>
AssemblyDependencyResolver
var resolver = new AssemblyDependencyResolver(pluginPath);
var assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
Preview4
Resources
Overview
- .NET Core 3 WinFormsでチャートコントロールが使えるようになった
- 階層型コンパイル(Tiered Compilation/TC)
- Tiered Compilation Preview in .NET Core 2.1 | .NET Blog
- .NET Core 3ではデフォルトで有効
- HTTP/2のサポート
- PowerShell Coreを含んだ .NET Core SDKのDockerイメージ
Preview5
Resources
Overview
- 新しい SqlClient
- NuGet Gallery | Microsoft.Data.SqlClient 1.0.19221.1-Preview
- 新しくサポートされた機能
- 常時暗号化 (Always Encrypted)
- Data Classification (データ分類)
- UTF-8のサポート
- .NET Frameworkでは
System.Data.dll
というアセンブリだった。 - 参考 Introducing the new Microsoft.Data.SqlClient | .NET Blog
- 単一のExeファイルを発行できるようになった
dotnet publish -r win10-x64 /p:PublishSingleFile=true
- 動かないので検証が必要
- 新元号「令和」に対応
Preview6
Resources
Overview
- AlpineのDockerイメージが用意された
- ReadyToRun (R2R)
- HTTPクライアント(HttpClient)でHTTP/2がサポートされた
ReadyToRun
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup> </Project>
Preview7
Resources
Overview
- Go Live
- 運用環境で使えるレベルになったということ。ただし実際に運用環境で使用する前には十分なテストが必要。
- .NET Core SDKのサイズが改善