C# 13の新機能を理解する――暗黙的なインデックスアクセスとallows ref struct
【C#で知っておくべき新機能】最新バージョンを徹底解説! 第7回
ダウンロード サンプルファイル (5.5 KB)
ジェネリクスの型制約に使えるようになったallows ref struct(allows ref struct)
C# 13では、ジェネリクスの型制約にallows ref structを指定できるようになり、ref構造体が型引数に指定可能になりました。
C# 7.2で使えるようになったref構造体は、その置き場所がスタックに限定されることから生ずる性能上のメリットと引き換えに、型引数になることができないなどの制約がありました(第2回を参照)。例えばSpan<T>構造体やReadOnlySpan<T>構造体はref構造体なので、それらを型引数とするジェネリック型を定義することができませんでした。
C# 13ではこの制約が緩和されて、アンチ制約(反制約)allows ref structを指定することでジェネリック型がref構造体を受入れ可能であることを示せます。例えば、以下のリストではクラスCが型パラメータにref構造体を受け入れることを許可していますが、メソッドMethodは引数がref構造体であっても問題ないように実装されている必要があります。
public class C<T> where T : allows ref struct
{
public void Method(scoped T p)
{
}
}
allows ref structは、ref構造体へのインタフェース実装のための機能です。C# 13では、以下のリストのようにref構造体がインタフェースを実装できるようになっています。
ref struct S : IFormattable
{
public string ToString(string? format, IFormatProvider? formatProvider) => "Hello";
}
ref構造体には、スタック上にしか配置できないという制約から、Box化できないという制約もあります。そのため、構造体SのインスタンスをIFormattable型の変数に代入して使うことはできません。ただし、ジェネリックなメソッドを定義して、それに渡す形であればBox化を回避できます。このとき、メソッドが型パラメータにref構造体を受入れ可能であることを示すのが、allows ref structです。
以下のリストの実行例のように、int型もS型も受け入れられて正しく実行されています。
static void Method<T>(T r) where T : IFormattable, allows ref struct
{
Console.WriteLine("{0}", r.ToString("", null));
}
Method<int>(100); // 100
var s = new S();
Method<S>(s); // Hello
allows ref structも万能ではなく、このアンチ制約を付与された場合には、ref構造体の制約に反するコードはコンパイルエラーとなります。例えば、メソッド内でインタフェース型の変数に代入して使うことはできません。
[NOTE]Box化
値型を参照型に変換、すなわちデータの置き場所をスタックからヒープへ変更することです。ボクシングともいいます。例えば整数型は値型なのでスタック上に配置されますが、Box化により参照型としてヒープ上へ配置することができます。反対に、ヒープ上にあるデータをスタック上に戻すことを非Box化(アンボクシング)といいます。
partialなプロパティとインデクサ(More partial members)
C# 13では、partialなプロパティとインデクサを宣言できるようになりました。
C#には、C# 2の頃から部分クラスという仕様があり、クラスを分割して定義できるようになっています。例えばあるクラスの定義において、ツールにより自動生成された部分と、開発者が記述する部分を明確に分けるための仕組みです。C# 3では部分メソッドが導入され、メソッドの宣言と実装を分けられるようになりました。さらに、C# 9では部分メソッドが拡張されました。
C# 13で導入されたpartialなプロパティとインデクサは、この拡張された部分メソッドの流れをくむものです。以下のリストは、部分プロパティと部分インデクサの実装例です。
public partial class C
{
// 部分プロパティ
public partial string Name { get; set; }
// 部分インデクサ
public partial int this[int index] { get; set; }
}
public partial class C
{
// Nameプロパティの実装
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
// インデクサの実装
private int[] _array = new int[10];
public partial int this[int index]
{
get => _array[index];
set => _array[index] = value;
}
}
var c = new C();
c.Name = "Tom";
Console.WriteLine("{0}", c.Name); // Tom
c[0] = 100;
Console.WriteLine("{0}", c[0]); // 100
この記事は参考になりましたか?
- 【C#で知っておくべき新機能】最新バージョンを徹底解説!連載記事一覧
-
- C# 14の新機能を理解する──fieldキーワードとユーザー定義複合代入演算子
- C# 14の新機能を理解する――extensionブロックとnull条件付き代入
- C# 13の新機能を理解する――暗黙的なインデックスアクセスとallows ref str...
- この記事の著者
-
WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
