一般的な答えと経験則:別のパイプラインでNullableを処理するオプション(たとえば、カスタムシリアライザーを作成する)がある object
場合、その固有のプロパティを使用して、Nullable固有のプロパティを使用します。したがって、一貫した思考の観点からHasValue
は、優先する必要があります。一貫した考え方は、詳細に多くの時間を費やさずに、より良いコードを書くのに役立ちます。たとえば、2番目の方法は何倍も効果的です(主にコンパイラーのインライン化とボクシングが原因ですが、それでも数値は非常に表現力があります)。
public static bool CheckObjectImpl(object o)
{
return o != null;
}
public static bool CheckNullableImpl<T>(T? o) where T: struct
{
return o.HasValue;
}
ベンチマークテスト:
BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
[Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1648.0
Clr : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1648.0
Core : .NET Core 4.6.25009.03, 64bit RyuJIT
Method | Job | Runtime | Mean | Error | StdDev | Min | Max | Median | Rank | Gen 0 | Allocated |
-------------- |----- |-------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|-----:|-------:|----------:|
CheckObject | Clr | Clr | 80.6416 ns | 1.1983 ns | 1.0622 ns | 79.5528 ns | 83.0417 ns | 80.1797 ns | 3 | 0.0060 | 24 B |
CheckNullable | Clr | Clr | 0.0029 ns | 0.0088 ns | 0.0082 ns | 0.0000 ns | 0.0315 ns | 0.0000 ns | 1 | - | 0 B |
CheckObject | Core | Core | 77.2614 ns | 0.5703 ns | 0.4763 ns | 76.4205 ns | 77.9400 ns | 77.3586 ns | 2 | 0.0060 | 24 B |
CheckNullable | Core | Core | 0.0007 ns | 0.0021 ns | 0.0016 ns | 0.0000 ns | 0.0054 ns | 0.0000 ns | 1 | - | 0 B |
ベンチマークコード:
public class BenchmarkNullableCheck
{
static int? x = (new Random()).Next();
public static bool CheckObjectImpl(object o)
{
return o != null;
}
public static bool CheckNullableImpl<T>(T? o) where T: struct
{
return o.HasValue;
}
[Benchmark]
public bool CheckObject()
{
return CheckObjectImpl(x);
}
[Benchmark]
public bool CheckNullable()
{
return CheckNullableImpl(x);
}
}
https://github.com/dotnet/BenchmarkDotNetが使用されました
PS。人々は、「一貫した思考のためにHasValueを好む」というアドバイスは関連性がなく、役に立たないと言っています。これのパフォーマンスを予測できますか?
public static bool CheckNullableGenericImpl<T>(T? t) where T: struct
{
return t != null; // or t.HasValue?
}
PPS人々はマイナスを続けますが、誰もがのパフォーマンスを予測しようと試みませんCheckNullableGenericImpl
。そして、コンパイラはあなたがで置き換えるの!=null
を助けませんHasValue
。HasValue
パフォーマンスに関心がある場合は、直接使用する必要があります。