C#:函数返回类型是否覆盖对象强制转换?

C#:函数返回类型是否覆盖对象强制转换?,c#,inheritance,unity3d,interface,polymorphism,C#,Inheritance,Unity3d,Interface,Polymorphism,我不确定用什么技术术语来描述这个场景,所以这里是我的案例 上下文: 我正在为一个游戏设计一个项目系统。目前,存在一个BaseGameItem类,该类包含基本参数,如Id、名称、图标等。。。 到目前为止,还存在从它派生的另一个类,称为PickupItem,它实现了IPickupItem。在我尝试通过项目生成器初始化这些对象之前,一切似乎都很好 关键思想是,存在一个 产卵器是指在初始化对象时,它会继续 吐出完全初始化的对象,如图所示: // ///初始化游戏项目: ///给定项目ID,构造BaseG

我不确定用什么技术术语来描述这个场景,所以这里是我的案例

上下文:

我正在为一个游戏设计一个项目系统。目前,存在一个BaseGameItem类,该类包含基本参数,如Id、名称、图标等。。。 到目前为止,还存在从它派生的另一个类,称为PickupItem,它实现了IPickupItem。在我尝试通过项目生成器初始化这些对象之前,一切似乎都很好

关键思想是,存在一个 产卵器是指在初始化对象时,它会继续 吐出完全初始化的对象,如图所示:

//
///初始化游戏项目:
///给定项目ID,构造BaseGameItem对象并将其返回给煽动者。
///引用ItemInfoTable以初始化对象参数。
/// 
///Paramater-Int-ID:提供的项目ID
///参数-out BaseGameItem:构造的对象返回给煽动者。
公共静态void初始值egameitem(int-id,out-BaseGameItem)
{
FItemInfoData itemInfoData=ItemTable.Find(x=>x.ItemID==id);
if(itemInfoData.ItemID!=id)
{
itemInfoData=ItemTable[0];
}
//检查项目是否为皮卡。如果是,则项目作为皮卡可替换项返回。
//否则,初始化为BaseGameItem。
item=itemInfoData.IsPickupItem?新的PickupReplacable():新的BaseGameItem();
item.SetItemName(itemInfoData.ItemName);
item.SetItemDescription(itemInfoData.ItemDescription);
item.SetItemIcon(itemInfoData.ItemIcon);
item.SetItemMesh(itemInfoData.ItemMesh);
}
我的问题如下:

  • 为了知道我应该返回哪个类或者该项实现的是什么接口,我在数据库中包含了一个布尔值,用于检查它是否是拾取对象。这是一个明智的决定吗?如果您能为我介绍在这种情况下使用的文章或设计模式,我将不胜感激
  • 然而,我主要关心的是返回类型。我正在使用out关键字并输出BaseGameItem对象。但是,在我的三元条件下,我可以将其初始化为派生的拾取项。功能输出是否会将其转换为BaseGameItem,从而丢失所有拾取功能?或者它是否将任何派生类解释为有效的返回类型?
  • 如果该对象以BaseGameItem的形式返回,那么接收者不应该意识到他们必须将其强制转换为派生类吗?如何解决这个问题呢?我是否只是返回一个布尔值,指示它是initialize函数中的一个拾取,以便接收方知道何时进行适当的强制转换
  • 为了知道我应该返回哪个类或者该项实现的是什么接口,我在数据库中包含了一个布尔值,用于检查它是否是拾取对象。这是一个明智的决定吗?如果您能为我介绍在这种情况下使用的文章或设计模式,我将不胜感激

  • 您正走在正确的轨道上:

  • 然而,我主要关心的是返回类型。我正在使用out关键字并输出BaseGameItem对象。但是,在我的三元条件下,我可以将其初始化为派生的拾取项。功能输出是否会将其转换为BaseGameItem,从而丢失所有拾取功能?或者它是否将任何派生类解释为有效的返回类型

  • 返回类型不会因向上投射而丢失功能:

    基类可以定义和实现虚拟方法,派生类可以重写它们,这意味着它们提供自己的定义和实现。在运行时,当客户机代码调用该方法时,CLR会查找对象的运行时类型,并调用虚拟方法的覆盖。因此,在源代码中,可以对基类调用方法,并执行派生类版本的方法

    --

  • 如果该对象以BaseGameItem的形式返回,那么接收者不应该意识到他们必须将其强制转换为派生类吗?如何解决这个问题呢?我是否只是返回一个布尔值,指示它是initialize函数中的一个拾取,以便接收方知道何时进行适当的强制转换

  • 否,“因此,在源代码中,您可以调用基类上的方法,并导致执行派生类版本的方法。”但是,当您需要派生类中的特定功能时,如
    pickupReplacable.Pickup()
    ,您必须先将其向下转换

    编辑:

    问题是,接收者如何知道是否应该投下基本项

    您始终可以使用
    is
    as
    关键字检查是否可以提取项目:

    if (item is PickupPlaceable)
    {
         var loot = (PickupPlaceable)item;
         loot.Pickup();
    }
    
    var loot = item as PickupPlaceable;
    if (loot != null)
    {
         loot.Pickup();
    }
    

    当您实际运行代码时发生了什么?我认为这个问题更适合于可能值得注意的是,您在强制转换时不会丢失对象的功能;您只是失去了对功能的访问。感谢您的详细回复!关于最后两点,我得到的印象是我的设计没有使用这种方法,对吗?因为BaseGameItem类根本没有实现最初的拾取接口。即使父类不使用虚方法,也可以用虚方法“污染”父类吗?请注意,为了练习,我打算派生另一个名为“Interactiable”的类,该类也不应具有拾取功能。@AAS.N当然可以使用抽象方法,但在您的情况下,我认为您应该使用接口,例如,您可以使用pick方法的Pickable接口,然后,您想要挑选的每一项都将实现该接口,可交互也是如此。@FilipRistic是的,这正是我最初设计它的方式。这个问题源于足总
    if (item is PickupPlaceable)
    {
         var loot = (PickupPlaceable)item;
         loot.Pickup();
    }
    
    var loot = item as PickupPlaceable;
    if (loot != null)
    {
         loot.Pickup();
    }