在此示例中,我正在为浏览器构建一个自动化库。有一个称为Mouse的基类,以及一个名为RoboticMouse和HumanMouse的派生类。
[假设我将鼠标实例化为HumanMouse,但在特定情况下,我希望它表现为RoboticMouse,例如,在需要它以更快地移动鼠标的部件上,我尝试做的是:
Mouse m = new HumanMouse();
m.Move();
(m as RoboticMouse).Move();
但是由于鼠标m被初始化为HumanMouse而不是RoboticMouse,所以我得到了NullReferenceException。
我可以做:
Mouse m = new HumanMouse();
m.Move();
m = new RoboticMouse(); m.Move();
但是这样,其中的值将被重新初始化,并且我想保持状态不变,例如,用于跟踪鼠标位置。
编辑:比较简单的例子:
这不适用于ClassB实例,并抛出null。
public class Program
{
public static void Run()
{
BaseClass instance = new ClassB();
instance.Increment();
Console.WriteLine(instance.Value);
(instance as ClassA).Increment();
Console.WriteLine(instance.Value);
Console.ReadLine();
}
}
class BaseClass
{
public int Value { get; set; }
public virtual void Increment()
{
Value++;
}
}
class ClassA : BaseClass
{
public override void Increment()
{
Value += 2;
}
}
class ClassB : BaseClass
{
public override void Increment()
{
Value += 4;
}
}
如果我遵循给出的使ClassB从ClassA继承的建议:
class ClassB : ClassA
{
public override void Increment()
{
Value += 4;
}
}
并尝试投射它:
public static void Run()
{
BaseClass instance = new ClassB();
instance.Increment();
Console.WriteLine(instance.Value);
(instance as ClassA).Increment();
Console.WriteLine(instance.Value);
Console.ReadLine();
}
它仍然运行该方法的ClassB版本...
编译器不知道如何从HumanMouse
转换为RoboticMouse
。
当您使用new
时,您正在有效地创建具有新值的新引用,因此有必要查看所见内容。
有两种解决方法。如果HumanMouse
确实是RoboticMouse
,则从HumanMouse
扩展RoboticMouse
如果HumanMouse
可转换为RoboticMouse
,则可以使用user-defined-conversion-operators声明如何进行转换。