假设有一个接口:IBankAccount;一个类SaverAccount,类SaverAccout继承自IBankAccount接口,如下图所示:
public interface IBankAccount
{public interface IBankAccount{void PayIn(decimal amount);bool Withdraw(decimal amount);decimal Balance{get;}}
}public class SaverAccount : IBankAccount
{private decimal _balance;public void PayIn(decimal amount) => _balance += amount;public bool Withdraw(decimal amount){if(_balance >= amount){_balance -= amount;return true;}WriteLine("Withdrawl attempt failed");return false;}public decimal Balance => _balance;public override string ToString() => $"Venus Bank Saver:Balance ={_balance,6:C}"$
}
正是因为继承关系,SaverAccount可以直接分配给IBankAccount接口,如下图所示:
IBankAccount venusAccount = new SaverAccount();
如果一个方法接受一个对象类型,现在希望访问IBankAccount成员,该怎么办呢?该对象类型没有IBankAccount接口成员。此时可以进行类型转换,把对象(也可以使用任何接口中的任意类型的参数,把它装化为需要的类型)转化为IBankAccount,再处理它:
public void WorkWithManyDifferentObjects(object o)
{IBankAccount account = (IBankAccount)o;//work with the account
}
只要总是给这个方法提供一个IBankAccount类型的对象,这就是有效的。当然,如果接受一个object类型的对象,有时就换传递无效的对象。此时会得到InvalidCastException 异常。在正常情况下接受异常从来都不好。此时应该使用 is 和 as 运算符。
不是直接进行类型的转化,而应该检查参数是否实现了接口IBankAccount。as 运算符的工作原理类似于层次结构中的 cast运算符——它返回对象的引用。然而,它从不抛出InvalidCastException异常,如果这个对象不是所要求的类型,这个运算符就返回null。
public void WorkWithManyDifferentObjects(object o)
{IBankAccount account = o as IBankAccount;if( account != null){//work with the account}
}
除了使用as运算符之外,还可以使用is运算符。 is运算符根据条件是否满足,对象是否使用指定的类型,返回true或者false.验证条件是true后,可以进行类型转换,因为现在,类型转换总会成功。
public void WorkWithManyDifferentObjects(object o)
{if(o is IBankAccount){IBankAccount account = (IBankAccount)o;//work with the account}
}
在类层次结构内部的类型转换,不会抛出基于类型转换的异常,而且使用is 和 as 运算符都是可以的。