真正的问题是反射和装配修补/挂钩。我将举一个简单的例子来展示我的问题,而不是太难理解主要问题。
所以让我们假设我有这些基本类:
public class Vehicle
{
public string Name;
public string Price;
public void DoSomething()
{
Main.Test(this);
}
}
public class Car : Vehicle
{
public int Wheels;
public int Doors;
}
在主要代码上我运行了这个:
public class Main
{
public void Start()
{
Car testCar = new Car()
{
Name = "Test Car",
Price = "4000",
Wheels = 4,
Doors = 4
};
testCar.DoSomething();
}
public static void Test(Vehicle test)
{
// Is this allowed ?
Car helloWorld = (Car) test;
}
}
好的,问题是:
是否允许转换(在静态方法Test中)?我会丢失汽车的属性,但保留汽车属性吗?
如果它错了,还有其他办法吗?
感谢。
答案 0 :(得分:5)
仅当传入的对象恰好是Vehicle
时,才允许Car
到Car
的强制转换。否则你会得到一个例外。
当类型错误时,有一个强制转换不会导致异常:
Car car = test as Car;
这绝不会抛出,但当Vehicle
不 Car
时,变量car
将为null
。您可以添加if
条件来测试强制转换是否成功:
Car car = test as Car;
if (car != null) {
...
}
Bus bus = test as Bus;
if (bus != null) {
...
}
Rv rv = test as Rv;
if (rv != null) {
...
}
然而,C#提供了一个更好的解决方案:方法重载可以让你完全避免投射。
public class Main {
public static void Test(Car test) {
... // This method will be called by Main.Test(this) of a Car
}
public static void Test(Bus test) {
... // This method will be called by Main.Test(this) of a Bus
}
public static void Test(Rv test) {
... // This method will be called by Main.Test(this) of an Rv
}
}
这很有效,因为当您进行this
调用时,编译器会知道Main.Test(this)
变量的确切类型。
答案 1 :(得分:2)
是的,演员是允许的,你不会失去"任何属性。但是,如果while($c = $filter->fetch()){
实际上不是Vehicle test
的实例,则您的演员会抛出Car
。
答案 2 :(得分:0)
是的,这是允许的。它的名字是downcasting。
请记住,可以通过类型内省检查以确定引用对象的类型是否确实是要转换为的类型或其派生类型。