You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型类型转换问题:Grid与PathNode实例化冲突求解

解决方案:利用泛型协变接口解决类型转换问题

核心问题分析

Grid<PathNode> 和 Grid<IPathNode> 是两个无继承关系的独立泛型类型,C# 默认不允许直接强制转换。要解决这个问题,我们可以通过协变泛型接口实现类型兼容,同时不需要给PathNode添加泛型参数。

具体修改步骤

1. 定义协变接口 IGrid<out T>

创建支持协变的接口,包含Grid<T>的所有公共只读属性(协变要求T只能作为输出,不能作为输入参数,当前Grid<T>的属性均为只读,符合要求):

public interface IGrid<out T>
{
    int Width { get; }
    int Height { get; }
    float CellSize { get; }
    Vector2 GridOffset { get; }
    T[,] GridObjects { get; }
}

2. 让 Grid<T> 实现该接口

修改Grid<T>类,实现IGrid<T>接口:

public class Grid<T> : IGrid<T>
{
    public int Width { get; }
    public int Height { get; }
    public float CellSize { get; }
    public Vector2 GridOffset { get; }
    public T[,] GridObjects { get; }

    public Grid(int width, int height, float cellSize, Vector3 gridOffset, Func<Grid<T>, int, int, T> createGridObjectMethod)
    {
        this.Width = width;
        this.Height = height;
        this.CellSize = cellSize;
        this.GridOffset = gridOffset;

        GridObjects = new T[width, height];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                GridObjects[x, y] = createGridObjectMethod(this, x, y);
            }
        }
    }
}

3. 修改 PathNode 的构造函数参数

将构造函数的Grid<IPathNode>参数改为IGrid<IPathNode>,这样可以接受任何实现了IGrid<IPathNode>的类型(包括Grid<PathNode>,因为协变允许IGrid<PathNode>隐式转换为IGrid<IPathNode>):

public class PathNode : IPathNode
{
    private readonly IGrid<IPathNode> grid; 
    public int X { get; }
    public int Y { get; }

    public PathNode PreviousNode;

    public PathNode(IGrid<IPathNode> grid, int x, int y)
    {
        this.grid = grid;
        this.X = x;
        this.Y = y;
    }

    public PathNode GetPathNode()
    {
        return this;
    }
}

4. 实例化 Grid<PathNode>

现在可以直接创建实例,无需强制转换:

Grid<PathNode> grid = new Grid<PathNode>(10, 10, 1, new Vector3(-5, -5, 0), (g, x, y) =>
{
    return new PathNode(g, x, y);
});

方案原理

协变接口IGrid<out T>中的out关键字表明T是协变类型,允许将IGrid<Derived>转换为IGrid<Base>(只要Derived继承自Base)。Grid<PathNode>实现了IGrid<PathNode>,而PathNode实现了IPathNode,因此IGrid<PathNode>可以隐式转换为IGrid<IPathNode>,完美匹配PathNode构造函数的参数要求。

内容的提问来源于stack exchange,提问作者Axvemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:10:28