C#继承泛型类时报错CS1503无法将GridXZ<BattleGridObject>转换为GridXZ<GridXZObject>
问题根源
你遇到的问题核心是C#的泛型不变性(Generic Invariance):即便BattleGridObject继承自GridXZObject,GridXZ<BattleGridObject>和GridXZ<GridXZObject>是完全独立的两个类型,不存在默认的隐式转换关系。
你的报错触发点在:BattleGridObject的构造函数要求传入GridXZ<GridXZObject>类型的参数,但你实际传入的是GridXZ<BattleGridObject>(也就是BattleGrid本身的类型),两个类型不兼容,自然会报转换失败。
修复方案
我们可以把GridXZObject也改成泛型类型,让它和所属的网格类型绑定,具体修改点如下:
- 修改
GridXZObject.cs为泛型抽象类:
public abstract class GridXZObject<T> where T : GridXZObject<T> { protected readonly GridXZ<T> Grid; protected readonly int X; protected readonly int Z; public GridXZObject(GridXZ<T> grid, int x, int z) { Grid = grid; X = x; Z = z; } public override string ToString() { return $"{X}, {Z}"; } }
- 修改
BattleGridObject.cs,继承时指定泛型参数为自身:
public class BattleGridObject : GridXZObject<BattleGridObject> { public BattleGridObject(GridXZ<BattleGridObject> grid, int x, int z) : base(grid, x, z) { } }
- 修改
GridXZ.cs的泛型约束,适配新的泛型基类:
public abstract class GridXZ<TGridXZObject> where TGridXZObject : GridXZObject<TGridXZObject> { 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); } } } }
其余BattleGrid.cs、BattleGridSystem.cs、OnGridXZObjectChangedEventArgs.cs无需修改即可正常编译运行。
补充说明
如果你不想修改基类的泛型设计,也可以在构造BattleGridObject的时候把传入的GridXZ<BattleGridObject>显式强制转换为GridXZ<GridXZObject>,但这种方式不安全,运行时可能出现类型错误,更推荐上述泛型绑定方案。
内容的提问来源于stack exchange,提问作者TH3UNKN0WN
相关产品推荐
相关产品推荐

