gpt4 book ai didi

具有继承的 C# 方法重载

转载 作者:太空宇宙 更新时间:2023-11-03 18:08:01 25 4
gpt4 key购买 nike

我一直认为 C# 通过查看方法调用接收器的运行时类型(即点之前的对象)在运行时动态解析方法调用。

但是,以下代码示例的工作方式有所不同。如果我在代码中使用 GenericSpaceShip,它会返回“Generic”;如果我使用 SpaceShip,它会返回“特定”。请注意,两种情况下的运行时类型都是 SpaceShip。

所以我的问题是:C# 如何解析 Visit 方法调用,为什么在这种情况下它查看编译时间而不是运行时类型?

请注意,这两个 Visit 方法具有不同的参数。正如 Patko 指出的那样,这意味着我不能在此处使用虚拟/覆盖。

class GenericSpaceShip
{
public void Visit(GenericPlanet planet)
{
Console.WriteLine("Generic");
}
}

class SpaceShip : GenericSpaceShip
{
public void Visit(Planet planet)
{
Console.WriteLine("Specific");
}
}

class GenericPlanet { }

class Planet : GenericPlanet { }

class Starter
{
static void Main(string[] args)
{
// SpaceShip ship = new SpaceShip();
GenericSpaceShip ship = new SpaceShip();
Planet planet = new Planet();

ship.Visit(planet); // => Generic
}
}

最佳答案

如果你想拥有真正的动态分辨率,那么你必须使用 dynamic 关键字,如下所示:

static void Main(string[] args)
{
dynamic ship = new SpaceShip();
Planet planet = new Planet();

ship.Visit(planet); // => Specific

// also
GenericPlanet genericPlanet = new GenericPlanet();
ship.Visit(planet); // Generic
}

在这种情况下,行为将类似于您所描述的 - 参数类型很重要。但是您最可能想要的是重写方法,如下所示:

class GenericSpaceShip
{
public virtual void Visit(GenericPlanet planet)
{
Console.WriteLine("Generic");
}
}

class SpaceShip : GenericSpaceShip
{
public override void Visit(GenericPlanet planet)
{
Console.WriteLine("Specific");
}
}

在这种情况下,如果您有 SpaceShip 实例和 GenericSpaceShip 实例的通用方法,则将调用特定方法,无论行星类型如何。在这种情况下,船舶类型很重要:

static void Main(string[] args)
{
SpaceShip ship = new SpaceShip();
Planet planet = new Planet();

ship.Visit(planet); // => Specific

// also
GenericPlanet genericPlanet = new GenericPlanet();
ship.Visit(planet); // Specific
}

如果使用 GenericSpaceShip,您将始终获得 Generic

关于具有继承的 C# 方法重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22589762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com