【发布时间】:2021-10-31 15:10:45
【问题描述】:
这是我发布的第一个问题,所以当我遗漏了什么或做错了什么时,请告诉我。 :)
我尝试创建一个用于创建网格的通用类。 所以我从那个泛型类继承并传递所有需要的参数。由于某种原因,编译器无法解决我的不同类的继承问题,我不确定其背后的原因是什么,因为我并不真正习惯于继承中的泛型。
错误信息:
错误 CS1503 参数 1:无法从“GridXZ<BattleGridObject>”转换为“GridXZ<GridXZObject>”BattleGridSystem.cs 7
因此编译器无法将BattleGridObject 转换为GridXZObject。这对我来说很奇怪,因为BattleGridObject 继承自GridXZObject。那么我在这里遗漏的明显点是什么?
据我所知,BattleGridObject 应该被强制转换/转换(?)到他的基类 GridXZObject 中,没有任何问题。
BattleGridSystem.cs
public class BattleGridSystem : MonoBehaviour
{
public BattleGrid Grid;
private void Awake()
{
Grid = new BattleGrid(10, 10, 5, Vector3.zero, (grid, x, z) => new BattleGridObject(grid, x, z));
}
}
BattleGrid.cs
public class BattleGrid : GridXZ<BattleGridObject>
{
public BattleGrid(int width, int height, float cellSize, Vector3 originPosition, Func<GridXZ<BattleGridObject>, int, int, BattleGridObject> createGridObject)
: base(width, height, cellSize, originPosition, createGridObject)
{
}
}
BattleGridObject.cs
public class BattleGridObject : GridXZObject
{
public BattleGridObject(GridXZ<GridXZObject> grid, int x, int z) : base(grid, x, z)
{
}
}
GridXZ.cs
public abstract class GridXZ<TGridXZObject> where TGridXZObject : GridXZObject
{
public event EventHandler<OnGridXZObjectChangedEventArgs> OnGridObjectChanged;
public readonly int Width;
public readonly int Height;
public readonly float CellSize;
protected readonly Vector3 OriginPosition;
protected readonly TGridXZObject[,] GridArray;
public GridXZ(int width, int height, float cellSize, Vector3 originPosition, Func<GridXZ<TGridXZObject>, int, int, TGridXZObject> createGridObject)
{
Width = width;
Height = height;
CellSize = cellSize;
OriginPosition = originPosition;
GridArray = new TGridXZObject[width, height];
for (var x = 0; x < GridArray.GetLength(0); x++)
{
for (var z = 0; z < GridArray.GetLength(1); z++)
{
GridArray[x, z] = createGridObject(this, x, z);
}
}
}
}
GridXZObject.cs
public abstract class GridXZObject
{
protected readonly GridXZ<GridXZObject> Grid;
protected readonly int X;
protected readonly int Z;
public GridXZObject(GridXZ<GridXZObject> grid, int x, int z)
{
Grid = grid;
X = x;
Z = z;
}
public override string ToString()
{
return $"{X}, {Z}";
}
}
OnGridXZObjectChangedEventArgs.cs
public class OnGridXZObjectChangedEventArgs : EventArgs
{
public int X;
public int Z;
}
【问题讨论】:
-
BattleGridObject需要GridXZ<GridXZObject>,但 lambda 工厂方法的参数是GridXZ<BattleGridObject>。这些不是可分配的类型。 -
我会尝试更改
BattleGridObject中的类型,但这仍然让我感到困惑,因为BattleGrid继承了GridXZ<GridXZObject>而BattleGridObject继承了GridXZObject。此外,我确信在BattleGridObject.中调用基本构造时会导致另一个转换错误 -
@JeremyLakeman 好的,但是我更改了
BattleGridSystem、BattleGrid和BattleGridObject内部的类型,但我找不到可行的解决方案。您能否向我解释为什么这些类型不可分配?我似乎遗漏了一些关于泛型和继承的重要信息。 -
"因此编译器无法将 BattleGridObject 转换为 GridXZObject。" - 这不是编译器错误所说的。它说它无法从
GridXZ<BattleGridObject>转换为GridXZ<GridXZObject>。这根本不是一回事——就像“香蕉是水果”但“一堆香蕉”不是“水果碗”一样。 (您无法从List<Banana>转换为List<Fruit>,因为您可以将 any 水果添加到List<Fruit>,但您不能将苹果添加到List<Banana>。)跨度>
标签: c# visual-studio unity3d generics inheritance