C# 重构将数据加载到不同类的两个类似方法
下面是两个示例方法,除了两个类引用之外,它们都非常相似。即,一个使用FishSettings和FishTileData,另一个使用WallSettings和WallTileData 如何编写一个方法,然后调用/引用调用它的类?我需要一个通用的方法,对吗C# 重构将数据加载到不同类的两个类似方法,c#,C#,下面是两个示例方法,除了两个类引用之外,它们都非常相似。即,一个使用FishSettings和FishTileData,另一个使用WallSettings和WallTileData 如何编写一个方法,然后调用/引用调用它的类?我需要一个通用的方法,对吗 void Fish(int id, GameObject tile, TileType tileType) { FishSettings settings = tile.GetComponent<FishSettin
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;
}
}
void Fish(int-id,GameObject tile,TileType-TileType)
{
FishSettings=tile.GetComponent();
foreach(数据库中的FishTileData数据(tileType))
{
if(data.Id==Id)
{
设置。加载(数据);
打破
}
}
}
空心墙(int-id、游戏对象平铺、平铺类型平铺类型)
{
WallSettings=tile.GetComponent();
foreach(数据库中的WallTileData数据(tileType))
{
if(data.Id==Id)
{
设置。加载(数据);
打破
}
}
}
无效加载数据(游戏对象新文件,平铺数据)
{
switch(_td.GetTileType())//这是基类TileData中的一个虚拟方法
{
case TileType.鱼:
FishSettings设置=_newfile.GetComponent();
设置。加载((鱼尾纹数据)_td);
打破
案例瓷砖类型。墙:
WallSettings设置=_newfile.GetComponent();
设置。荷载((墙砖数据)\u td);
打破
违约:
打破
}
}
乍一看,它可能是抽象基类中虚拟方法的候选者
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
}
公共抽象类游戏对象
{
公共虚拟void加载设置(int-id)
{
瓦氏变种=
这是鱼?TileType.鱼:
这是Wall?TileType.Wall:TypeType.Null;
变量设置=
这是Fish?tile.GetComponent():
这是Wall?tile.GetComponent():
无效的
foreach(数据库中的var数据(tileType))
{
如果(data.Id=Id)
{
设置。加载(数据);
打破
}
}
}
}
公共类鱼:游戏组件
{
//其他鱼类
}
公共类墙:GameComponent
{
//墙类的其余部分
}
是的,您可以将这两个方法合并为一个通用方法,前提是您可以修改所有其他涉及的类以实现某些接口。您需要使具有相同名称(Id
和Load
)的方法可以从约束到接口的泛型参数调用(假设类型没有您可以控制的公共父级)
接口IHasId{int Id{get;}
接口ILoadable{void Load(TData数据);}
void LoadItem(int-id、游戏对象磁贴、TileType-TileType)
其中:TSettings:iladable,TData:IHasId
{
t设置设置=tile.GetComponent();
foreach(数据库中的TData数据(tileType))
{
如果(data.Id=Id)
{
设置。加载(数据);
打破
}
}
}
类墙设置:ILoadable。。。
WallTileData类:IHasId,。。。
像这样使用它
LoadItem<WallSettings, WallTileData>(...);
LoadItem(…);
注:
- 搜索所有对象以按id查找项目看起来很慢。您可能希望在
数据库中提供ID查找
- 如果满足性能目标,您可以尝试使用
,而不是泛型dynamic
- 重写整个加载序列以基于存储中的数据创建对象可能是更好的选择
if(data.Id=Id)
应该是if(data.Id=Id)
意思是等于,而不是赋值?我在记事本中键入了==,很好的回答,lolI想知道我会怎么做,使用我提供的少量信息,将搜索更改为更高效,尽管当前的方法需要大约2秒来加载3000个瓷砖?不过我知道这有多糟糕,在GameObject类中创建抽象getter类型和抽象方法GetComponent,然后在Fish/Wall类中实现它怎么样?在您当前的解决方案中,您将有许多ifs
LoadItem<WallSettings, WallTileData>(...);