2017-02-15 37 views
0

下面是兩個示例方法,除了兩個類引用外,它們都非常相似。即。一個使用FishSettings和FishTileData其他WallSettings和WallTileData。重構兩種類似的方法將數據加載到不同的類

如何編寫單個Method然後調用/引用它所調用的類?我需要一個通用方法嗎?

void Fish(int id, GameObject tile, TileType tileType) 
    { 
     FishSettings settings = tile.GetComponent<FishSettings>(); 
     foreach (FishTileData data in DataBase(tileType)) 
     { 
      if (data.Id == id) 
      { 
       settings.Load(data); 
       break; 
      } 
     } 
    } 
void Wall(int id, GameObject tile, TileType tileType) 
    { 
     WallSettings settings = tile.GetComponent<WallSettings>(); 
     foreach (WallTileData data in DataBase(tileType)) 
     { 
      if (data.Id == id) 
      { 
       settings.Load(data); 
       break; 
      } 
     } 
    } 

void LoadData(GameObject _newTile, TileData _td) 
{ 
    switch (_td.GetTileType()) // This is a virtual Method in the base class : TileData 
    { 
     case TileType.Fish: 
      FishSettings settings = _newTile.GetComponent<FishSettings>(); 
      settings.Load((FishTileData)_td); 
      break; 
     case TileType.Wall: 
      WallSettings settings = _newTile.GetComponent<WallSettings>(); 
      settings.Load((WallTileData)_td); 
      break; 
     default: 
      break; 
    }     
} 
+2

Load的定義是怎樣的? –

+3

與您當前的問題完全無關,但它看起來像是從數據庫加載「所有內容」,然後手動搜索以找到您感興趣的一個項目。幾乎總是最好將搜索推入數據庫,並讓* it *更加高效地找到正確的項目。 –

+1

'if(data.Id = id)'應該是'if(data.Id == id)'意味着等於而不是分配值? – peval27

回答

-2

這乍看上去像它可能是在抽象基類的虛方法的候選人。

public abstract class GameObject 
{ 
    public virtual void LoadSettings(int id) 
    { 
     var tileType = 
      this is Fish? TileType.Fish: 
      this is Wall? TileType.Wall: TypeType.Null; 
     var settings = 
      this is Fish? tile.GetComponent<FishSettings>(): 
      this is Wall? tile.GetComponent<WallSettings>(): 
          null; 

     foreach (var data in DataBase(tileType)) 
     { 
      if (data.Id = id) 
      { 
       settings.Load(data); 
       break; 
      } 
     } 
    } 
} 
public class Fish: GameComponent 
{ 
    // rest of Fish class 
} 
public class Wall: GameComponent 
{ 
    // rest of Wall class 
} 
+2

如何在GameObject類中創建抽象獲取器類型和抽象方法GetComponent,然後在Fish/Wall類中實現它?在你目前的解決方案中,你會有很多ifs – MistyK

0

是的,您可以將這兩個方法合併爲一個通用方法,假設您可以修改所有其他涉及的類來實現某些接口。您需要使用相同名稱(IdLoad)的方法從通用參數約束到接口(假定類型沒有可以控制的公共父類)調用。

interface IHasId { int Id {get;}} 
interface ILoadable<TData> { void Load(TData data);} 

void LoadItem<TSettings, TData>(int id, GameObject tile, TileType tileType) 
     where : TSettings : ILoadable<TData>, TData : IHasId 
{ 
    TSettings settings = tile.GetComponent<TSettings>(); 
    foreach (TData data in DataBase(tileType)) 
    { 
     if (data.Id = id) 
     { 
      settings.Load(data); 
      break; 
     } 
    } 
} 

class WallSettings : ILoadable<WallTileData>, ... 
class WallTileData : IHasId,... 

,並使用它像

LoadItem<WallSettings, WallTileData>(...); 

注:

  • 通過所有搜索對象的ID查找項目看起來很慢。您可能需要提供身份證查詢您的DataBase
  • 你可以嘗試使用dynamic,而不是仿製的,如果滿足您的性能目標
  • 改寫整個裝載序列來創建基於從存儲器中的數據對象可能是更好的選擇。
相關問題