Question

Je travaille sur une méthode d'extension qui est uniquement applicable aux types de référence. Je pense, cependant, il est actuellement la boxe et unboxing la valeur. Comment puis-je éviter cela?

namespace System
{
    public static class SystemExtensions
    {
        public static TResult GetOrDefaultIfNull<T, TResult>(this T obj, Func<T, TResult> getValue, TResult defaultValue)
        {
            if (obj == null)
                return defaultValue;
            return getValue(obj);
        }
    }
}

Exemple d'utilisation:

public class Foo
{
    public int Bar { get; set; }
}

Dans une méthode:

Foo aFooObject = new Foo { Bar = 1 };
Foo nullReference = null;

Console.WriteLine(aFooObject.GetOrDefaultIfNull((o) => o.Bar, 0));  // results: 1
Console.WriteLine(nullReference.GetOrDefaultIfNull((o) => o.Bar, 0));  // results: 0
Était-ce utile?

La solution

Ce n'est pas la boxe. Où pensez-vous qu'il est la boxe? Si c'est parce que vous avez regardé l'IL autour de « == », ne le laissez pas vous tromper - le JIT va décider ce qu'il faut faire ici. Il a la possibilité de générer du code natif différent pour chaque couple (T, TResult). En fait, le code sera partagé pour tous les types de référence, et diffèrent pour les types de valeur. Donc, vous finiriez avec:

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)

Cela dit, si vous voulez limiter votre méthode d'extension à des types de référence, faire:

public static TResult GetOrDefaultIfNull<T, TResult>
    (this T obj, Func<T, TResult> getValue, TResult defaultValue)
    where T : class

Il y aura toujours une boîte à l'IL, mais ne vous inquiétez pas - pas la boxe va effectivement se produire. Après tout, ce que pourrait être acculé? Vous fournissez une référence, et les références ne sont jamais eux-mêmes en boîte -. Seules les valeurs de type valeur sont mis en boîte

Autres conseils

Simplement, il n'y a rien dans ce code qui nécessiterait la boxe. Il sont scénarios où la boxe est inévitable, et il y a aussi opcodes supplémentaires pour combler l'écart entre les types valeur / ref ( constrained ) dans certains cas.

Mais pas dans ce cas; pas réelle boxe nécessaire (le JIT peut enlever quelques cas de boîte - mais pas tous, malheureusement)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top