将ClassA.Method()称为ClassB.Method(),但仅影响ClassA值,两个类都源自相同的BaseClass

问题描述 投票:1回答:1

在此示例中,我正在为浏览器构建一个自动化库。有一个称为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版本...

c# object casting polymorphism state
1个回答
0
投票

编译器不知道如何从HumanMouse转换为RoboticMouse

当您使用new时,您正在有效地创建具有新值的新引用,因此有必要查看所见内容。

有两种解决方法。如果HumanMouse确实是RoboticMouse,则从HumanMouse扩展RoboticMouse

如果HumanMouse可转换为RoboticMouse,则可以使用user-defined-conversion-operators声明如何进行转换。

© www.soinside.com 2019 - 2024. All rights reserved.