【C# 11】INumber インターフェース

Youtube を漁っていたら Build のオンデマンドを見つけたので試してみた。

www.youtube.com

INumber インターフェースを使ってみた

C# 11 を使うには .NET 7 の環境が必要なので、こちらを用意しておく。

dotnet.microsoft.com

C# 11 の新機能ということで、抽象化されたインターフェースを使うと例えば扱えるデータの型を絞れるみたい。例えば総和を求めるプログラムを下記の様に書く。

var result = AddAll(new[] { 1, 2, 3, 4, 5 });
Console.WriteLine(result);

int AddAll(int[] values)
{
    int result = 0;
    foreach (var value in values)
    {
        result += value;
    }
    return result;
}

これを実行すると 15 が出力される。もちろん、整数値だけの計算であればこのプログラムで問題ないのだが、例えば整数以外にも対応する必要が出てきた場合、メソッドのオーバーロードを作成するか、ジェネリックを使用して任意の型で定義するかになる。前者は全ての型に対して実装しなければならず、面倒なので後者の方法で実装してみる。

とりあえず、int の部分をジェネリック T に置き換えておく。

もちろん、このままでは T を int として扱うことはできないので where キーワードで制約したいと考えるだろう。しかし、ジェネリック型制約ではインターフェースやクラスなどしか扱えない。そこで使用するのが INumber インターフェース。using ディレクティブに System.Numerics を追加して実装していく。

using System.Numerics;

var result = AddAll(new[] { 1, 2, 3, 4, 5 });
Console.WriteLine(result);

T AddAll<T>(T[] values) where T : INumber<T>
{
    T result = T.AdditiveIdentity;
    foreach (var value in values)
    {
        result += value;
    }
    return result;
}

AdditiveIdentity を検索すると「加法単位元」といい、「元の値にどんな値を加えても、元の値が変化しないような値」らしい。要するにゼロってことですな。でも、ただのゼロで初期化しようとすると int 型とみなされて型不一致になってしまうみたい。

これで実行すると同じように、15 が出力されるし、配列の一部を例えば下記のように変更すると

var result = AddAll(new[] { 1, 2, .3, 4, 5 });

自動的に小数を計算して 12.3 という結果を出力させることができる。

何かしらの値を計算させる場合、数値以外の値を弾きたい場合はジェネリック型制約に INumber インターフェースを使用してあげれば良い。

参考

docs.microsoft.com

イベントのお知らせ

2022年6月19日(日)に MS Tech Camp #16 学生によるLT大会!!を開催します。Microsoft に関するテーマであれば自由で、プログラミング関係以外にも例えば Office 関係や Windows の便利機能などであれば何でもOKです!

mspjp.connpass.com

当日は Youtube ライブ配信にてお送りします。LT 枠もまだまだ募集中ですので、ぜひご参加ください~

Microsoft の学生コミュニティに興味がある学生さんへ

日本では約10名が活動している Microsoft Learn Student Ambassadors は、Microsoft 製品や技術を広める活動を行っています。興味がある方は下記リンクを覗いてみてください。応募方法や特典など、役立つ情報をまとめてみました!

blog.takunology.jp

学生の皆さまの参加をお待ちしております!