拳击转换还是身份转换?
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 显然是错误的,因为没有从 object
到 System.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>
是用接口上的通用约束定义的,它会在用它初始化时封装任何实现此接口的结构。
我在阅读 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 显然是错误的,因为没有从 object
到 System.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>
是用接口上的通用约束定义的,它会在用它初始化时封装任何实现此接口的结构。