Это не бокс. Как вы думаете, это это бокс? Если это потому, что вы посмотрели на IL вокруг "==", не позволяйте этому обмануть вас - JIT решает, что делать здесь. У него есть возможность сгенерировать собственный нативный код для каждой (T
, TResult
) пары. Фактически, код будет общим для всех ссылочных типов и различаться для типов значений. В итоге вы получите:
T = string, TResult = int (native code #1)
T = Stream, TResult = byte (native code #2)
T = string, TResult = byte (native code #2)
T = Stream, TResult = string (native code #3)
Сказав это, если вы хотите ограничить свой метод расширения ссылочными типами, сделайте так:
public static TResult GetOrDefaultIfNull<T, TResult>
(this T obj, Func<T, TResult> getValue, TResult defaultValue)
where T : class
В IL все еще будет коробка, но не волнуйтесь - на самом деле никакого бокса не произойдет. В конце концов, что может быть в штучной упаковке? Вы предоставляете ссылку, а сами ссылки никогда не заключаются в квадраты - только значения типа значения упаковываются.