1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Preview】ref 構造体のジェネリック制限の緩和

Posted at

概要

C# の ref 構造体はスタックに配置する必要がある都合上、これまでのバージョンだとジェネリック引数に渡せませんでした。これが .net9 preview6 で制限が緩和されました。

public static string Create<TState>(int length, TState state, SpanAction<char, TState> action) where TState : allows ref struct;

ReadOnlySpan<char> input = "Hello, World!";
var str = string.Create(input.Length, input, static (stringBuffer, input) => input.ToLowerInvariant(stringBuffer));
Assert.Equal("hello, world!", str);

標準ライブラリの変更とか

System.Action<T> System.Func<T> などの汎用のデリゲートで、T に ref 構造体を使えるようになっています。確認していませんが、List<T> 等のジェネリック型がヒープに置かれる型を除けば、 ref 構造体を使えるようになっている可能性があります。

Action<ReadOnlySpan<int>> act = span =>
{
    Assert.Equal([1, 2, 3], span);
};
act([1, 2, 3]);

Func<ReadOnlySpan<int>> func = () => [1, 2, 3];
Assert.Equal([1, 2, 3], func());

ref 構造体のフィールドにも使用できます。

file ref struct ValueHolder<T> where T : allows ref struct
{
    public T Value;
    public ValueHolder(T value) => Value = value;
}

var holder = new ValueHolder<Span<int>>([1, 2, 3]);
Assert.Equal([1, 2, 3], holder.Value);

インターフェイスも継承できる!

なんと ref 構造体がインターフェイスを継承できるようになりました。つまり、ジェネリック引数に「特定のメソッドがある」制約をもたせることができます。

file interface INumber
{
    int GetNumber();

    static int GetNumberGeneric<T>(T number) where T : INumber, allows ref struct
        => number.GetNumber();
}

file ref struct RefStructNumber : INumber
{
    private Span<int> _span;

    internal RefStructNumber(Span<int> span) => this._span = span;

    public int GetNumber()
    {
        var result = 0;
        foreach (var n in this._span)
            result += n;
        return result;
    }
}

var number = new RefStructNumber([1, 2, 3]);
Assert.Equal(6, INumber.GetNumberGeneric(number));

ボックス化が起こるコードは書けませんが、ref 構造体を使える場所が増えそうです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?