【发布时间】:2020-03-24 07:07:41
【问题描述】:
我在阅读第三版C# in Depth时偶然发现了这个问题。这本书在 P.74 的表 3.2 中有以下内容。
class Sample<T> where T : IComparable<T> | 有效:Sample<int>(装箱转换),无效: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 真的可以被视为拳击转换吗?否则我对拳击和泛型类型转换的整个想法是错误的?
【问题讨论】:
-
如果不知道您实际询问的是书中的什么文字,就不可能完全理解您的问题。请修正您的问题,以便将您的问题所依据的书中的逐字引用包含在内。
-
我不明白你对 1.3 有什么问题,虽然我没有读过这本书,所以我不知道它是怎么说的。恕我直言,没有测试,应该没问题,因为
OtherSample实现了一个继承IComparable<T>的接口,这意味着它也在实现IComparable<T>。 -
" 当 public class Sample
where T : IComparable 签名更改为 public class Sample where T : IComparableExtended 时,即使 1.1 也成为编译时错误。" ——嗯,你期待什么? int没有实现IComparableExtended<int>。