2017-02-15 39 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,而不是仿制的,如果满足您的性能目标
  • 改写整个装载序列来创建基于从存储器中的数据对象可能是更好的选择。
相关问题