![](/img/trans.png)
[英]Is it possible for a method in ClassA to be triggered by an event in ClassB?
[英]Calling a ClassA.Method() as ClassB.Method() but only affecting ClassA values, both classes are deriving from the same BaseClass
在这个例子中,我正在为浏览器构建一个自动化库。 有一个名为 Mouse 的基类,以及名为 RoboticMouse 和 HumanMouse 的派生类。
假设我将鼠标实例化为 HumanMouse,但在一个特定场合,我希望它表现得像 RoboticMouse,例如,在我需要它更快地移动鼠标的部分,我尝试做的是:
Mouse m = new HumanMouse();
m.Move();
(m as RoboticMouse).Move();
但是我得到一个 NullReferenceException,因为 Mouse m 被初始化为 HumanMouse 而不是 RoboticMouse。
我可以:
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声明如何进行转换。
根据问题编辑进行编辑
让我给你举个动物的例子。
假设ClassA
是一只动物, ClassB
是一只猫。 所以Cat
扩展了动物并为Move
函数设置了一个新的行为。
猫永远是动物,但不是每只动物都是猫。 这就是为什么
// This works
Animal a = new Cat();
// This does not work
Cat a = new Animal();
现在,当您将猫分配给动物并覆盖Move
函数时,这意味着无论您是否以动物的身份访问它,猫都将始终以猫的身份移动。 你不能把猫扔给动物,因为它已经是动物了。 (cat as Animal)
什么都不做。
同样,您不能将classB
为classA
因为 B 已经是 A 并且将始终表现为 B。
public abstract class Mouse {
public int x {get; set;}
public int y {get; set;}
public Mouse(x,y) {
this.x = x;
this.y = y;
}
public virtual void Move() {
this.x++;
this.y++;
}
public virtual void Move(x, y) {
this.x+= x;
this.y+= y;
}
}
public class HumanMouse: Mouse {
// whatever
public HumanMouse(): base(1,1) {
}
}
public class RoboticMouse: Mouse {
public static int
// whatever
public RoboticMouse(): base(2,2) {
}
}
Mouse m = new HumanMouse();
m.Move();
m.Move(1,2);
// or
Mouse m2 = new RoboticMouse();
m.Move();
m.Move(m2.x,m2.y);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.