ufcpp-live / UfcppLiveAgenda

@ufcpp live streaming agenda
MIT License
24 stars 2 forks source link

.NET 8 RC1 #77

Closed ufcpp closed 11 months ago

ufcpp commented 1 year ago

配信URL: https://www.youtube.com/watch?v=qaEfydb4B4U

公式アナウンス:

C# がらみ:

↓コンパイルエラーに。

using System.Collections.Immutable;

IImmutableList<int> list = [1, 2, 3]; // 適切な Create メソッドがないと怒られる。

foreach (var x in list)
{
    Console.WriteLine(x);
}

↓通るようになった(ref readonly)。

int x = 123;

m(in x); // in 引数同様、in 呼び可能。

m(ref x); // ref 付けても OK に。

m(x); // 一応 in 省略も、エラーではなく警告。
m(456); // これも警告のみ。

static void m(ref readonly int x) => Console.WriteLine(x);
ufcpp commented 1 year ago

恒 例 行 事

https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/

ufcpp commented 1 year ago

ref readonly の一番のモチベーション:

using System.Runtime.InteropServices;

// こういうのとか
var s1 = MemoryMarshal.CreateReadOnlySpan(0, 1);

// こういうのが大変まずい。
int x = 123;
var y = 256;
var s2 = MemoryMarshal.CreateReadOnlySpan(x + y, 1);

// 一時変数が使ってる領域どこか未定義。下手したらレジスターで完結しててどこも指せない。
ufcpp commented 1 year ago

VS の更新したらちゃんと、↓がInlineArray使うようになった。

Span<string> s = ["", "a", "abc"];

foreach (var x in s) Console.WriteLine(x);

Array.Empty 最適化(配列 or ReadOnly 系インターフェイスのみ)もかかる。

IReadOnlyList<int> list = []; // Array.Empty<int>() と一緒。

dotnet build だと使わない… また微妙にコンパイラーのバージョン違うんだ。

ufcpp commented 1 year ago

VS側コンパイラーでもまだ IImmutableList (インターフェイス)のコレクション式はダメ。

ufcpp commented 1 year ago

プライマリコンストラクター引数の2重バッキングフィールドに対する警告出るようになってた。

class A(int x)
{
    private int _x = x; // CS9124
    public int X { get; } = x; // CS9124
    public int Y => x; // この行がなければ別に CS9124 は出ない。
}
ufcpp commented 1 year ago

https://twitter.com/ufcpp/status/1702562859564273980

readonly系インターフェイスの場合はイテレーターと同じような(GetEnumeratorで新規インスタンス作らない)型を生成して使うようになる予定(作業真っ最中)。

roslyn の 69623 GA までには(merge 済みなので多分次のリリースには)入るはず。

ufcpp-live commented 1 year ago
public static void m1(IEnumerable<int>? x)
{
    foreach (var item in x ?? []) // Array.Empty<int>()
    {
    }
}

public static void m2(IList<int>? x)
{
    foreach (var item in x ?? []) // new List<int>()
    {
    }
}
ufcpp-live commented 1 year ago
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// こいつはマジでまずい。
// temporary 変数の参照って何?
int x = 123;
var y = 1;
var span = MemoryMarshal.CreateReadOnlySpan(x + y, 1);

// これのせいで、前までは in にできなかった。
// 前までは ref だったので、
ref readonly var r = ref x;
var s1 = MemoryMarshal.CreateReadOnlySpan(
    ref Unsafe.AsRef(in r), // in を ref に置き換える Unsafe やくざ
    1);

// これからは in r が行ける。
var s2 = MemoryMarshal.CreateReadOnlySpan(in r, 1);
ufcpp-live commented 1 year ago
using System.Runtime.InteropServices;

var s1 = MemoryMarshal.CreateReadOnlySpan(123, 1);
Console.WriteLine(s1[0]);

var s2 = MemoryMarshal.CreateReadOnlySpan(456, 1);
Console.WriteLine(s2[0]);

var s3 = MemoryMarshal.CreateReadOnlySpan(789, 1);
Console.WriteLine(s3[0]);

Console.WriteLine(s1[0]); // こいつも 789 に書き変わってる
Console.WriteLine(s2[0]); // 同上
// (環境依存、未定義動作)
ufcpp-live commented 1 year ago
struct A
{
    // 現在有効
    public readonly ref readonly int M1(ref readonly int x) => ref x;

    // 可能性出てきた
    public readonly ref readonly int M2(readonly ref readonly int x) => ref x;
}
ufcpp-live commented 1 year ago

primary ctor 化

image

ufcpp-live commented 1 year ago
partial class A(int x) // 未使用引数警告あり
{
    public int x;
    public int Y => x; // この x はフィールドの x。
}
ufcpp-live commented 1 year ago
class B
{
    public int _x;

    /// <summary>
    /// コンストラクター
    /// </summary>
    /// <param name="x">x のさまりー</param>
    public B(int x) { _x = x; }
}

↓ IDE0290 リファクタリング

/// <summary>
/// コンストラクター
/// </summary>
/// <param name="x">x のさまりー</param>
class B(int x)
{
    public int _x = x;
}
ufcpp-live commented 1 year ago
/// <summary>
/// クラス
/// </summary>
class B
{
    public int _x;

    /// <summary>
    /// コンストラクター
    /// </summary>
    /// <param name="x">x のさまりー</param>
    public B(int x) { _x = x; }
}

↓ IDE0290

/// <summary>
/// クラス
/// </summary>
/// <remarks>
/// コンストラクター
/// </remarks>
/// <param name="x">x のさまりー</param>
class B(int x)
{
    public int _x = x;
}
ufcpp-live commented 1 year ago

<summary/> はバグったww

image

ufcpp-live commented 1 year ago

image

永久ループはしなかった。

ufcpp-live commented 1 year ago
using System.Runtime.InteropServices;

List<int> list = [1, 2, 3, 4, 5, 6, 7, 8, 9];

CollectionsMarshal.SetCount(list, 4);

foreach (var item in list)
{
    Console.Write($"{item} ");
}
Console.WriteLine();

CollectionsMarshal.SetCount(list, 8); // Grow で再アロケーション要らないくらいの長さの時は値が復活。
//CollectionsMarshal.SetCount(list, 100); // Grow で再確保必要な場合は復活しない。

foreach (var item in list)
{
    Console.Write($"{item} ");
}
Console.WriteLine();