Open ufcpp opened 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) { }
}
runtime 100898 で params コレクション導入。 まあ、ReadOnlySpan ばっかり。 元々ある ReadOnlySpan 引数に params 足したのが多め。 残りは Write/Format 系。
[CollectionBuilder(typeof(A), nameof(Create))]
class A
{
// Builder の方はいまだ、この GetEnumerator がないとダメ。
public IEnumerator GetEnumerator() => throw new NotImplementedException();
public static A Create(ReadOnlySpan<object> x) => new();
}
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> _) { }
}
IDE側間に合わないコンパイルエラーの例
UTF-8 にできない文字列を u8 リテラルで書くとなる。
void Struct<T>(T items)
where T : struct, IEnumerable<int>
{
// たったこれだけでアロケーションかかる。
// GetEnumerator が IEnumerator<T> を返すせい。
// struct enumerator 受け取れない。
foreach (var item in items)
{
}
}
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 の方しか見つからない。
// (名前空間違うせい)
}
}
}
// アロケーション除けができる IEnumerable はこんな感じになる。
// (.NET では、型システムに手を入れない限り無理。)
interface IPerformantEnumerable<T>
{
assosiated type TState;
TState GetState();
bool MoveNext(ref TState state, out T value);
}
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();
}
拡張メソッドも見るようになってた。 (記憶上、多分今回から。)
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 _) { }
}
配信URL: https://www.youtube.com/watch?v=WPgx-UPFxk4
あんまり大きな追加なく。
.NET SDK の方は累積アプデのみっぽく。↑ 1日遅れで .NET 9 Preview 3 出てた。IDE 周り:
C#
時間余ったらまたブログで書いたネタでも話す?