![](/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.