![](/img/trans.png)
[英]Does casting an Object in C# always return a Reference to the initial object
[英]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);
}
我的問題如下:
為了知道我應該返回哪個類或該項目正在實現什么接口,我在數據庫中包含了一個布爾值來檢查它是否是一個 Pickup 對象。 這是一個明智的決定嗎? 如果您能將我引向此類場景中使用的文章或設計模式,我將不勝感激。
您使用工廠方法走在正確的軌道上:
然而,我主要關心的是返回類型。 我正在使用 out 關鍵字並輸出 BaseGameItem 對象。 但是,在我的三元條件下,我可以將其初始化為派生的 Pickup 項目。 函數輸出是否會將其轉換為 BaseGameItem,從而失去所有 Pickup 功能? 或者它是否將任何派生類解釋為有效的返回類型?
返回類型不會因向上轉換而失去功能:
基類可以定義和實現虛擬方法,派生類可以覆蓋它們,這意味着它們提供自己的定義和實現。 在運行時,當客戶端代碼調用該方法時,CLR 查找對象的運行時類型,並調用虛擬方法的覆蓋。 因此,在您的源代碼中,您可以調用基類上的方法,並導致執行該方法的派生類版本。
-- 多態(C# 編程指南)
如果對象無論如何都作為 BaseGameItem 返回,接收者難道不應該知道他們必須將它轉換為派生類嗎? 如何解決這個問題,我是否簡單地返回一個布爾值,指示它是 initialize 函數中的一個 Pickup,以便接收者知道何時適當地投射?
不,“因此,在您的源代碼中,您可以調用基類上的方法,並導致執行派生類的方法版本。” 但是,當您需要派生類中的特定功能時,例如PickupPlaceable.Pickup()
,您必須先將其向下轉換
編輯:
問題變成了,接收者如何知道是否應該投射基礎項目。
您始終可以使用is
或as
關鍵字檢查是否可以拾取物品:
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.