我可能錯誤地描述了標題,但基本上我想要做的是具有同一對象的列表,它具有不同的通用類型。C#多種類型的通用列表
這個例子,我有一個塔防遊戲,它使用基於Tile的地圖。所以我有層(瓦片層,物體層,ai層)。所以我有這個類:
public class Layer<T>{
// The name of the layer
private String name;
// All the cells in this layer
private Cell<T>[] cells;
public Layer(Map map, String name){
cells = new Cell<T>[map.Width * map.Height];
this.name = name;
CreateCells();
}
/// <summary>
/// Fills the array of cells with blank, unoccupied cells
/// </summary>
private void CreateCells(){
var index = 0;
for (var x = 0; x < cells.Length; x++){
for (var y = 0; y < cells.Length; y++){
cells[index] = new Cell<T>(x, y);
index++;
}
}
}
// Gets the array of cells in this layer
public Cell<T>[] GetCells(){
return cells;
}
/// <summary>
/// Gets a cell at a specific index/coordinate
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>The cell at the X and Y coordinate/index</returns>
public Cell<T> GetCellAt(int x, int y){
foreach (var c in cells){
if (c.GetX() != x || c.GetY() != y) continue;
return c;
}
throw new Exception("Cell not found at " + x+"x"+y);
}
/// <summary>
/// Gets the name of this layer
/// </summary>
/// <returns></returns>
public String GetName(){
return name;
}
}
現在,這是好的,這意味着我可以指定持有Object類型的層。在圖塊圖層中,我希望可以容納圖塊的單元格,對象中我希望圖層可以容納對象等的地方等。
問題是,當我嘗試在地圖類中創建圖層列表時。我對Java(?)中所謂的「通配符」類型的語法不太確定。
我試過了,沒有成功:
private List<Layer<dynamic>> layers;
它怪胎的時候我這樣做:
layers = new List<Layer<dynamic>>();
layers.Add(new Layer<Tile>(this, "tiles"));
所以我顯然是在利用這種不正確的語法。
我應該在這種情況下怎麼辦?
更新1:
在從人的建議,我已經使用內層的常用方法的接口(送電池和什麼不可以)嘗試。這種設計的問題在於,圖層需要類型T才能確定每個單元格可以使用的對象類型。
更新2:
我不能想出一個辦法做到這一點任何其他方式,所以我決定去與此解決方案:
刪除仿製藥一起和(幾乎)而不是給細胞類型T爲乘員,我給它的類型的GameObject。現在大多數事情都是從遊戲對象(塔,瓦片,障礙物,粒子)繼承而來,然而AI相關的代碼都沒有,所以我不得不改變我的路徑查找代碼來做到這一點。
我現在有以下幾點:
public class Layer{
// The name of the layer
private String name;
// All the cells in this layer
private Cell[] cells;
}
泛型已經從Cell類以及去除:
public class Cell{
// The object inside this cell
private GameObject occupant; // Note the new occupant type
// The width and height of the cell in world coordinates
public const float WIDTH = 1, HEIGHT = 1;
// The coordinate of this cell
private int x, y;
}
現在我使用Cell類中的泛型方法如下所示:
/// <summary>
/// Gets the occupant in this cell
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T GetOccupant<T>() where T : GameObject{
return occupant as T;
}
所以這裏的代碼,按預期工作:
layers = new List<Layer>();
layers.Add(new Layer(this, "tiles"));
GetLayer("tiles").GetCellAt(5, 5).SetOccupant(new EnemyScientist(null, 5, 1, 6));
Enemy e = GetLayer("tiles").GetCellAt(5, 5).GetOccupant<Enemy>();
儘管不是最好看的代碼,地圖系統只會用於這個遊戲,所以我並不特別擔心編寫可重複使用的代碼,主要是功能代碼。忽略我剛剛將一個敵人卡在瓦片層的事實,但我會添加某種便宜的檢查(typeof)以確保我不會把它搞亂。
'新的List <層
您是否考慮過使用通用位來實現接口?該列表可以是'List>'將不起作用,除非您將它限制爲'out'泛型類型並且僅限於'class'類型。 'out'也只適用於接口和代理,這意味着你不能僅僅通過類型本身來做到這一點。 –
我可以去掉泛型類型的層,而是有三層繼承和接口是,這實際上可能是考慮到每一層都會有相同的字段 – Gibbo