簡體   English   中英

從C#中的單個方法返回多個類型

[英]Return multiple types from single method in C#

我正在研究Xna / C#中的基本游戲和2D引擎,我正在嘗試簡化其中的一些內容。 我有一個來自引擎的Entity2D基類和兩個特定於游戲的類繼承它:Tower和Enemy。 在我的引擎中,而不是有兩個單獨的列表,一個用於Towers,一個用於Enemies,我想將它們組合成一個通用列表。 然后,我有問題,當我需要從列表中返回一個塔或從列表中返回一個敵人。 我知道我可以使用引擎對象的類型轉換:

class Entity2D {...} //engine object
class Tower : Entity2D {...} //game specific
class Enemy : Entity2D {...} //game specific

//In engine:
public Entity2D GetEntity(int index) { ...return objects[index];}

//Somewhere in the game
{
    Enemy e = GetEntity(0) as Enemy;
    if(e != null)
        //Enemy returned

    Tower t = GetEntity(0) as Tower;
    if(t != null)
        //Tower returned
}

當然這看起來效率很低。

我也查了一下is關鍵字,看起來像這樣:

Entity2D entity = GetEntity(0);
if(entity is Tower)
{
    Tower t = (Tower)entity;
    t.DoTowerThings();
}

仍然會導致返回一個基礎對象並使用更多的內存來創建第二個對象並對其進行類型轉換。

真正好的是,如果有辦法做這樣的事情:

//In engine:
public T GetEntity(int index) 
{ 
    if(T == Tower) //or however this would work: (T is Tower), (T as Tower), etc
        return objects[index] as Tower;
    else if(T == Enemy) 
        return objects[index] as Enemy;
    else return null;
}

Enemy e = GetEntity(0);

但是那打破了發動機和游戲分離的引擎部分

我正在尋找最清晰,最有效的內存方式,同時仍然讓Entity2D成為引擎,並避免在引擎中使用Tower或Enemy。

歡迎大家提出意見!

謝謝!

就快到了!

//In engine:
public T GetEntity<T>(int index) where T : Entity2D
{ 
    return objects[index] as T;
}
//Somewhere else:
Enemy e = GetEntity<Enemy>(0);

注意:如果objects[index]不是T ,則它將返回null

但是,如果是我的游戲,我會為每種類型的對象保留單獨的列表。

你可以這樣做,( Github上的完整代碼

public T GetEntity<T>(int index) where T : Entity2D
{
    return list.ElementAt(index) as T;
}

如果元素不是預期的類型,它將返回null。

Tower t = GetEntity<Tower>(0);

如果你必須消除返回值的歧義,那么代碼的結構是不好的,對象在邏輯上並不相似,你最好有兩個列表,每個類型有一個單獨的訪問器。

但是,如果類型非常相似,並且您只需要很少消除它們之間的歧義,那么執行以下操作: -

abstract class GameEntity : Entity2D
{
  abstract public void TowerOnlyFunction (args); // need to look up exact syntax, but you get the idea
  abstract public void EnemyOnlyFunction (args);

  void CommonFunctions (args);
}

class Tower : GameEntity
{
  public void TowerOnlyFunction (args)
  {
    // code
  }
  public void EnemyOnlyFunction (args)
  {
    // empty
  }
}

class Enemy : GameEntity
{
  public void TowerOnlyFunction (args)
  {
    // empty
  }
  public void EnemyOnlyFunction (args)
  {
    // code
  }
}

//Somewhere in the game
void DoSomethingWithTower ()
{
  GameEntity e = GetEntity(0);
  e.TowerOnlyFunction ();
}

暫無
暫無

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

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