はじめに
いままでのC#のジェネリックでは、オペレーター(+や-)を使用できないため、int型float型など型ごとに関数を実装する必要がありましたが、INumberを使うと1つの関数を実装するだけで済ます。
個人的になんでこういうこと出来ないのか昔から疑問でしたが、ついに実装されるときが来て嬉しいです。
ただ、2022/04/26時点でまだ正式な機能ではなくプレビュー機能としての提供となります。
環境設定
Visual Studio 2022を起動しプロジェクトの作成
- プロジェクト名:ココでは「INumberTest」とします。
- プロジェクトテンプレート:コンソール無印(.NET Frameworkじゃない方)
- フレームワーク:.NET 6.0
プレビュー機能を有効化
INumberTest.csprojをテキストエディタで編集し、PropertyGroupタグ内に以下を追記する。
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>
追記後の例
<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
System.Runtime.Experimentalをインストール
NuGetからインストールします。
コード記述
合計を計算する関数の例
Program.cs
var values = new double[5] { 1, 2, 3, 4, 5 };
var sum = Sum(values);
Console.WriteLine(sum);
static T Sum<T>(IEnumerable<T> values) where T : INumber<T>
{
T sum = T.Zero;
foreach (var value in values)
{
sum += value;
}
return sum;
}
出力結果
15
マチンの公式の例
Program.cs
MachinsFormulaTest();
/// <summary>
/// マチンの公式
/// </summary>
/// <param name="count">計算回数。1未満を設定すると0を返す。</param>
/// <returns>PI/4(円周率の4分の1)</returns>
static T MachinsFormula<T>(int count) where T : INumber<T>
{
var _4 = T.Create(4);
var _5 = T.Create(5);
var _239 = T.Create(239);
T sum = T.Zero;
for (int k = 1; k <= count; k++)
{
int odd = (2 * k - 1);// 奇数(int型)
var _odd = T.Create(odd);// 奇数(T型)
sum +=
_4 *
(Pow(-T.One, k + 1) / _odd) *
Pow(T.One / _5, odd) +
(Pow(-T.One, k) / _odd) *
Pow(T.One / _239, odd);
}
return sum;
}
static void MachinsFormulaTest()
{
Console.WriteLine($"MachinsFormulaTest()");
Console.WriteLine($"float");
{
var pi = MachinsFormula<float>(17) * 4;
Console.WriteLine($"{pi}");
}
Console.WriteLine($"double");
{
var pi = MachinsFormula<double>(17) * 4;
Console.WriteLine($"{pi}");
}
Console.WriteLine($"decimal");
{
var pi = MachinsFormula<decimal>(20) * 4;
Console.WriteLine($"{pi}");
}
}
出力結果
MachinsFormulaTest()
float
3.1415925
double
3.1415926535897944
decimal
3.1415926535897932384626433820
Create系関数の動作
関数 | 説明 |
---|---|
CreateChecked | 値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲から外れる値に対しては,オーバーフロー例外を投げます. |
CreateSaturating | 値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲の外側にあるすべての値を飽和させます。 |
CreateTruncating | 値から現在の型のインスタンスを作成します。現在の型の表現可能な範囲から外れる値は切り捨てられます。 |
参考にしたサイト