簡體   English   中英

C#:函數返回類型是否覆蓋對象轉換?

[英]C#: Does function return type override object casting?

我不確定使用什么技術術語來描述這種情況,所以這是我的情況。

語境:

我正在為游戲設計一個物品系統。 目前,存在一個 BaseGameItem 類,其中包含基本參數,如 Id、名稱、圖標等......到目前為止,還有另一個派生自它的類,稱為實現 IPickupItem 的 PickupItem。 在我嘗試通過 Item Spawner 初始化這些對象之前,一切似乎都很好。

關鍵思想是,存在一個持久數據庫,生成器在初始化對象時引用該數據庫,然后繼續吐出完全初始化的對象,如下所示:

        /// <summary>
    /// Initialize Game Item:
    /// Given an Item ID, constructs a BaseGameItem object and returns it to instigator.
    /// Refers to ItemInfoTable to initialize object parameters.
    /// </summary>
    /// Paramater - Int ID: The provided Item ID
    /// Parameter - out BaseGameItem Item: The constructed object returned to the instigator.
    public static void InitializeGameItem(int id, out BaseGameItem item)
    {
        FItemInfoData itemInfoData = ItemTable.Find(x => x.ItemID == id);

        if(itemInfoData.ItemID != id)
        {
            itemInfoData = ItemTable[0];
        }

        // Check if item is a Pickup. If so, then item is returned as a PickupPlaceable.
        // Otherwise, initialize to BaseGameItem.
        item = itemInfoData.IsPickupItem ? new PickupPlaceable() : new BaseGameItem();

        item.SetItemName(itemInfoData.ItemName);
        item.SetItemDescription(itemInfoData.ItemDescription);
        item.SetItemIcon(itemInfoData.ItemIcon);
        item.SetItemMesh(itemInfoData.ItemMesh);
    }

我的問題如下:

  1. 為了知道我應該返回哪個類或該項目正在實現什么接口,我在數據庫中包含了一個布爾值來檢查它是否是一個 Pickup 對象。 這是一個明智的決定嗎? 如果您能將我引向此類場景中使用的文章或設計模式,我將不勝感激。
  2. 然而,我主要關心的是返回類型。 我正在使用 out 關鍵字並輸出 BaseGameItem 對象。 但是,在我的三元條件下,我可以將其初始化為派生的 Pickup 項目。 函數輸出是否會將其轉換為 BaseGameItem,從而失去所有 Pickup 功能? 或者它是否將任何派生類解釋為有效的返回類型?
  3. 如果對象無論如何都作為 BaseGameItem 返回,接收者難道不應該知道他們必須將它轉換為派生類嗎? 如何解決這個問題,我是否簡單地返回一個布爾值,指示它是 initialize 函數中的一個 Pickup,以便接收者知道何時適當地投射?
  1. 為了知道我應該返回哪個類或該項目正在實現什么接口,我在數據庫中包含了一個布爾值來檢查它是否是一個 Pickup 對象。 這是一個明智的決定嗎? 如果您能將我引向此類場景中使用的文章或設計模式,我將不勝感激。

您使用工廠方法走在正確的軌道上:

  1. 然而,我主要關心的是返回類型。 我正在使用 out 關鍵字並輸出 BaseGameItem 對象。 但是,在我的三元條件下,我可以將其初始化為派生的 Pickup 項目。 函數輸出是否會將其轉換為 BaseGameItem,從而失去所有 Pickup 功能? 或者它是否將任何派生類解釋為有效的返回類型?

返回類型不會因向上轉換而失去功能:

基類可以定義和實現虛擬方法,派生類可以覆蓋它們,這意味着它們提供自己的定義和實現。 在運行時,當客戶端代碼調用該方法時,CLR 查找對象的運行時類型,並調用虛擬方法的覆蓋。 因此,在您的源代碼中,您可以調用基類上的方法,並導致執行該方法的派生類版本。

-- 多態(C# 編程指南)

  1. 如果對象無論如何都作為 BaseGameItem 返回,接收者難道不應該知道他們必須將它轉換為派生類嗎? 如何解決這個問題,我是否簡單地返回一個布爾值,指示它是 initialize 函數中的一個 Pickup,以便接收者知道何時適當地投射?

不,“因此,在您的源代碼中,您可以調用基類上的方法,並導致執行派生類的方法版本。” 但是,當您需要派生類中的特定功能時,例如PickupPlaceable.Pickup() ,您必須先將其向下轉換

編輯:

問題變成了,接收者如何知道是否應該投射基礎項目。

您始終可以使用isas關鍵字檢查是否可以拾取物品:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM