ufcpp-live / UfcppLiveAgenda

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

.NET 9 Preview 3 / Visual Studio 17.10 Preview 3 #89

Open ufcpp opened 3 months ago

ufcpp commented 3 months ago

配信URL: https://www.youtube.com/watch?v=WPgx-UPFxk4

あんまり大きな追加なく。

.NET SDK の方は累積アプデのみっぽく。 ↑ 1日遅れで .NET 9 Preview 3 出てた。

IDE 周り:

C#

時間余ったらまたブログで書いたネタでも話す?

ufcpp commented 3 months ago

params コレクションがらみ

とりあえず一番需要ありそうな ReadOnlySpan

static void Params(params ReadOnlySpan<byte> data)
{
}

Params(1, 2);

自作 & Add の引数の型で見るように(コレクション初期化子と同じような仕様に戻った)

using System.Collections;

static void ParamsA(params A data)
{
}

ParamsA(1, "");

A a = [1, ""];

class A : IEnumerable
{
    public void Add(int _) { }
    public void Add(string _) { }
    public IEnumerator GetEnumerator() => throw new NotImplementedException();
}

オーバーロード

A.Params(1, 2); // ReadOnlySpan に行くみたい(この点はコレクション式と一緒)

class A
{
    public static void Params(params ReadOnlySpan<byte> data) { }
    public static void Params(params Span<byte> data) { }
    public static void Params(params byte[] data) { }
}

[] の有無でオーバーロード解決変わるやつ

A.Params(1, 2); // これだと Span<int> に行く
A.Params([1, 2]); // これだと ReadOnlySpan<byte> に行く

class A
{
    public static void Params(params ReadOnlySpan<byte> data) { }
    public static void Params(params Span<int> data) { }
}
ufcpp commented 3 months ago

runtime 100898 で params コレクション導入。 まあ、ReadOnlySpan ばっかり。 元々ある ReadOnlySpan 引数に params 足したのが多め。 残りは Write/Format 系。

ufcpp-live commented 3 months ago
[CollectionBuilder(typeof(A), nameof(Create))]
class A
{
    // Builder の方はいまだ、この GetEnumerator がないとダメ。
    public IEnumerator GetEnumerator() => throw new NotImplementedException();
    public static A Create(ReadOnlySpan<object> x) => new();
}
ufcpp-live commented 3 months ago
await Task.Delay(1);

C.Params(1, 2);

C.Params(stackalloc int[2]); // これ、もとから書けた。

ReadOnlySpan<int> span = stackalloc int[2]; // これもいいじゃん…
// 近々書けるようになる予定あり。

await Task.Delay(1);

class C
{
    public static void Params(params ReadOnlySpan<int> _) { }
}
ufcpp-live commented 3 months ago

IDE側間に合わないコンパイルエラーの例

image

UTF-8 にできない文字列を u8 リテラルで書くとなる。

ufcpp-live commented 3 months ago
void Struct<T>(T items)
    where T : struct, IEnumerable<int>
{
    // たったこれだけでアロケーションかかる。
    // GetEnumerator が IEnumerator<T> を返すせい。
    // struct enumerator 受け取れない。
    foreach (var item in items)
    {
    }
}
ufcpp-live commented 3 months ago
namespace MyLibrary
{
    public static class ArrayEx
    {
        public static int Sum<T>(this T[] array)
        {
            return default;
        }
    }
}

namespace System.Linq
{
    public static class EnumerableEx
    {
        public static int Sum<T>(this IEnumerable<T> array)
        {
            return default;
        }

    }
}

namespace ConsoleApp1
{
    class Program
    {
        public void M()
        {
            // Sum がなぜか IEnumerable の方しか見つからない。
            // (名前空間違うせい)
        }
    }
}
ufcpp-live commented 3 months ago
// アロケーション除けができる IEnumerable はこんな感じになる。
// (.NET では、型システムに手を入れない限り無理。)
interface IPerformantEnumerable<T>
{
    assosiated type TState;

    TState GetState();
    bool MoveNext(ref TState state, out T value);
}
ufcpp-live commented 3 months ago
using System.Collections;

// 「params なのに [] ないの違和感ありますね」
static void ParamsA(params A data) { }

// そうね、[] 付けるか。
static void ParamsAs(params A[] data){}

ParamsA(1, "");
ParamsAs(1, "");

class A : IEnumerable
{
    public void Add(int _) { }
    public void Add(string _) { }

    // 邪悪。
    // これの静で As の方がコンパイル通っちゃう。
    public static implicit operator A(int _) => new A();
    public static implicit operator A(string _) => new A();

    public IEnumerator GetEnumerator() => throw new NotImplementedException();
}
ufcpp-live commented 3 months ago

拡張メソッドも見るようになってた。 (記憶上、多分今回から。)

using System.Collections;

static void ParamsA(params A data) { }

ParamsA(['a']);

class A : IEnumerable
{
    public struct Dummy;
    public void Add(Dummy _) { }
    public IEnumerator GetEnumerator() => throw new NotImplementedException();
}

static class AEx
{
    public static void Add(this A a, char _) { }
}