次のコードでこのエラーが発生するのはなぜですか?
void Main()
{
int? a = 1;
int? b = AddOne(1);
a.Dump();
}
static Nullable<int> AddOne(Nullable<int> nullable)
{
return ApplyFunction<int, int>(nullable, (int x) => x + 1);
}
static Nullable<T> ApplyFunction<T, TResult>(Nullable<T> nullable, Func<T, TResult> function)
{
if (nullable.HasValue)
{
T unwrapped = nullable.Value;
TResult result = function(unwrapped);
return new Nullable<TResult>(result);
}
else
{
return new Nullable<T>();
}
}
コードにはいくつかの問題があります。 1つ目は、型はnull可能でなければならないということです。 where T: struct
を指定することで表現できます。 where TResult: struct
もnull許容型として使用しているため、指定する必要があります。
where T: struct where TResult: struct
を修正したら、戻り値のタイプ(これは間違っていました)やその他の多くの項目も変更する必要があります。
これらのエラーをすべて修正して単純化した後、次のように仕上げます。
static TResult? ApplyFunction<T, TResult>(T? nullable, Func<T, TResult> function)
where T: struct
where TResult: struct
{
if (nullable.HasValue)
return function(nullable.Value);
else
return null;
}
Nullable<T>
をT?
に書き換えると、読みやすくなります。
また、?:
を使用して1つのステートメントとしてそれを書くこともできますが、私はそれが読みやすいとは思いません:
return nullable.HasValue ? (TResult?) function(nullable.Value) : null;
あなたはこれを拡張メソッドに入れたいかもしれません:
public static class NullableExt
{
public static TResult? ApplyFunction<T, TResult>(this T? nullable, Func<T, TResult> function)
where T: struct
where TResult: struct
{
if (nullable.HasValue)
return function(nullable.Value);
else
return null;
}
}
次に、次のようなコードを記述できます。
int? x = 10;
double? x1 = x.ApplyFunction(i => Math.Sqrt(i));
Console.WriteLine(x1);
int? y = null;
double? y1 = y.ApplyFunction(i => Math.Sqrt(i));
Console.WriteLine(y1);
エラーが示すように、コンパイラーはTがすでにnull可能でないことを保証しません。 Tに制約を追加する必要があります。
static Nullable<T> ApplyFunction<T, TResult>(Nullable<T> nullable,
Func<T, TResult> function) : where T : struct
where TResult : struct