拳击转换还是身份转换?

Boxing Conversion or Identity Conversion?

我在阅读 C# in Depth 第三版时偶然发现了这个问题。该书在 P.74 的 Table 3.2 中有以下内容。

class Sample<T> where T : IComparable<T> | Valid: Sample<int> (boxing conversion), Invalid: Sample<FileInfo>

让我们考虑以下问题。

using System;

public class Program
{
    public static void Main()
    {
        Sample<int> s1 = new Sample<int>();                 // ---(1.1)
        Sample<object> s2 = new Sample<object>();           // ---(1.2)
        Sample<OtherSample> s3 = new Sample<OtherSample>(); // ---(1.3)
        s1.Print();
        s2.Print();
    }
}

public class Sample<T> where T : IComparable<T> {
    public void Print() {
        Console.WriteLine(this);
    }
}

public class OtherSample : IComparableExtended<OtherSample> {
    public int CompareTo(OtherSample obj) {
        return 0;
    }
}

public interface IComparableExtended<T> : IComparable<T> {}

显然,1.2 显然是错误的,因为没有从 objectSystem.IComparable<object> 的隐式引用转换。我对 1.1 也确实没有问题,除了书上说它是 Boxing Conversion。现在,int 实际上是 Int32 结构的别名,它通过层次结构 Object->ValueType->Int32 继承。这将接口 System.IComparable<T> 实现为 IComparable<Int32>,这就是 1.1 正确的原因。据我了解,where T : IComparable<T> 的意思是 T 应该是实现 IComparable 的东西。我认为 Int32 实现了这个接口,因此满足 Sample<T> 的类型约束。从这个意义上说,这真的是书中所暗示的拳击转换吗?或者这是身份转换?

1.3 使这与书中的内容更加混乱和矛盾。当 public class Sample<T> where T : IComparable<T> 签名更改为 public class Sample<T> where T : IComparableExtended<T> 时,即使 1.1 也成为编译时错误。

所以我的问题是,1.1真的可以被认为是拳击转换吗?还是我对装箱和泛型类型转换的整个想法是错误的?

这是一个拳击转换。

快速查看文档将带您进入 Boxing and Unboxing (C# Programming Guide) 页面,该页面以以下文本开头:

Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type.

(强调我的)

由于 Sample<T> 是用接口上的通用约束定义的,它会在用它初始化时封装任何实现此接口的结构。