12

Tをクラスに制約するジェネリックメソッドで、生成されるMSILコードにボクシング命令が含まれるのはなぜですか?

Tは参照型に制約されているので、生成されたコードはボクシングを実行する必要がないので、私はこれに非常に驚いていました。

これがc#コードです:

protected void SetRefProperty<T>(ref T propertyBackingField, T newValue) where T : class
{
    bool isDifferent = false;

    // for reference types, we use a simple reference equality check to determine
    // whether the values are 'equal'.  We do not use an equality comparer as these are often
    // unreliable indicators of equality, AND because value equivalence does NOT indicate
    // that we should share a reference type since it may be a mutable.

    if (propertyBackingField != newValue)
    {
        isDifferent = true;
    }
}

生成されたILは次のとおりです。

.method family hidebysig instance void SetRefProperty<class T>(!!T& propertyBackingField, !!T newValue) cil managed
{
    .maxstack 2
    .locals init (
        [0] bool isDifferent,
        [1] bool CS$4$0000)
    L_0000: nop 
    L_0001: ldc.i4.0 
    L_0002: stloc.0 
    L_0003: ldarg.1 
    L_0004: ldobj !!T
    L_0009: box !!T
    L_000e: ldarg.2 
    L_000f: box !!T
    L_0014: ceq 
    L_0016: stloc.1 
    L_0017: ldloc.1 
    L_0018: brtrue.s L_001e
    L_001a: nop 
    L_001b: ldc.i4.1 
    L_001c: stloc.0 
    L_001d: nop 
    L_001e: ret 
}

ボックス!!Tの説明に注意してください。

なぜこれが生成されているのですか?

これを回避する方法は?

4

4 に答える 4

2

box引数が参照型の場合、命令は何もしないため、命令によるパフォーマンスの低下を心配する必要はboxありません。命令が作成されていることさえ奇妙ですがbox(おそらくコード生成時の怠惰/より簡単な設計?)。

于 2009-09-17T15:12:20.223 に答える
0

これは設計上意図されていると思います。T を特定のクラスに制約していないため、オブジェクトにダウンキャストする可能性が最も高いです。したがって、IL にボクシングが含まれていることがわかります。

このコードを where T : ActualClass で試してみます

于 2009-09-09T16:00:59.447 に答える