Open
Description
using System;
using System.Runtime.CompilerServices;
readonly struct Container<T>
{
private readonly T value;
public Container(T value) => this.value = value;
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public TOther GetValueOrDefault<TOther>() where TOther : struct =>
(value as TOther?).GetValueOrDefault(); // boxing occurs here
}
static class Program
{
static void Main()
{
var container = new Container<Guid>(Guid.Empty);
var count = 0;
while (true)
{
// call a method where boxing may occur
if (container.GetValueOrDefault<Guid>() != default)
Console.WriteLine("...");
// monitor GC events due to boxing
var newCount = GC.CollectionCount(0);
if (newCount != count)
Console.WriteLine(count = newCount);
}
}
}
Expression (value as TOther?).GetValueOrDefault()
in Container<T>.GetValueOrDefault
can be considered as a simplified form of value is TOther ? (TOther) (object) value : default(TOther)
. Because JIT eliminates boxing in the latter form (when compiled in Release mode and started without debugger), it would be great if it could eliminate boxing in the former as well.
$env:ProgramFiles\dotnet\shared\Microsoft.NETCore.App\5.0.0-alpha.1.19564.1\.version
c77948d92a2f950140f09384f057cb893ec3955a
5.0.0-alpha.1.19564.1
category:cq
theme:boxing
skill-level:expert
cost:medium