强制类型转换和类型转换是两种不同的方式,都能把表达式从一种数据类型转换成另一种数据类型。
表达式可以使用强制类型转换运算符(<type>)转换成另一种类型。
long l = 1000L;
int i = (int)l;
object o = new Random();
Random r = (Random)o;
如果类型不兼容,就会抛出InvalidCastException的实例。对于数字来说,这表明接收类型无法表示转换后的值。对于类来说,其中一个类型必须派生自另一个类型(这一点对结构体也自然成立)。
除了_强制类型转换_,另一种做法是使用is运算符进行_类型转换_。它通常用于引用类型和可空类型。
object o = new Random();
if (o is Random rand)
{
int ii = rand.Next();
// now, do something random
}
如果你需要检测对象的精确类型,那么is可能有点过于宽松,因为对于某个类,以及它直接或间接派生的任何类和接口,它都会返回 true。在这种情况下,typeof和Object.GetType()就是解决办法。
object o = new List<int>();
o is ICollection<int> // true
o.GetType() == typeof(ICollection<int>) // false
o is List<int> // true
o.GetType() == typeof(List<int>) // true
我们的足球俱乐部football-match-reports在联赛中势如破竹,因此你受邀来做更多工作,这次是安全通行证打印系统。
后勤人员的类层次结构如下
TeamSupport (interface)
├ Chairman
├ Manager
└ Staff (abstract)
├ Physio
├ OffensiveCoach
├ GoalKeepingCoach
└ Security
├ SecurityJunior
├ SecurityIntern
└ PoliceLiaison
该层次结构的完整实现已作为本练习源代码的一部分提供。
传给安全通行证生成器的所有数据都已通过验证,并保证非空。
请实现SecurityPassMaker.GetDisplayName()方法。对于所有派生自Staff的类的实例,它应返回Title字段的值;否则应返回“Too Important for a Security Pass”。
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Manager());
// => "Too Important for a Security Pass"
spm.GetDisplayName(new Physio());
// => "The Physio"
请修改SecurityPassMaker.GetDisplayName()方法。除了以下一点外,它的行为应与任务 1 相同:如果该员工是安全团队的成员(类型为Security或其派生类之一),则应在名称后显示文本“ Priority Personnel”。
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Physio());
// => "The Physio"
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior Priority Personnel"
请修改SecurityPassMaker.GetDisplayName()方法。除了以下一点外,它的行为应与任务 2 相同:对于类型为SecurityJunior、SecurityIntern和PoliceLiaison的实例,不应显示文本“ Priority Personnel”。
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior"