当我阅读C#in Depth的第三版时偶然发现了这个问题。该书在第74页的表3.2中具有以下内容。
[C0 | | 有效:
:class Sample<T> where T : IComparable<T
(装箱转换),无效Sample<int>
让我们考虑以下内容。
Sample<FileInfo>
显然,1.2是错误的,因为没有从
的东西。我认为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> {}
到object
的隐式引用转换。我真的对1.1也没有问题,只是书说它是Boxing Conversion。现在,System.IComparable<object>
实际上是int
结构的别名,该结构通过层次结构Int32
继承。这将接口Object->ValueType->Int32
实现为System.IComparable<T>
,这就是1.1正确的原因。据我了解,IComparable<Int32>
的意思是T应该是实现IComparablewhere T : IComparable<T>
实现了此接口,因此满足了Int32
的类型约束。从这个意义上说,这真的像书中所建议的那样是拳击转换吗?还是此身份转换?1.3使这与书中的内容更加混乱和矛盾。当
Sample<T>
签名更改为public class Sample<T> where T : IComparable<T>
时,即使1.1也会导致编译时错误。所以我的问题是,1.1是否真的可以视为拳击转换?否则我对装箱和通用类型转换的整个想法是错误的?
这是拳击转换。
快速浏览文档将使您进入public class Sample<T> where T : IComparableExtended<T>
页面,该页面以以下文本开头:
装箱是将值类型转换为类型对象或由该值类型实现的任何接口类型的过程。
(重点是我的)
由于Boxing and Unboxing (C# Programming Guide)在接口上定义了通用约束,因此在初始化该接口时,它将包装实现该接口的所有结构。