无法从类转换为泛型接口



编辑:已更新以包含实际代码

我遇到了一些自定义通用接口的问题,我不完全确定该怎么办。我得到的错误是:

无法从Map转换为IMap<ICell>

当我试图将Map作为参数传递给接受IMap<ICell>的方法时,会弹出该错误。我在下面粘贴了示例代码。需要明确的是,FieldOfView没有使用ICellIMap中未定义的任何内容。

public class Map : IMap<Cell>
{
private FieldOfView _fieldOfView;
public int Width { get; }
public int Height { get; }
public Map(int width, int height)
{
Width = width;
Height = height;
_fieldOfView = new FieldOfView(this as IMap<ICell>);
_fieldOfView = new FieldOfView((IMap<ICell>)this);
}
public IEnumerable<Cell> GetAllCells()
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
yield return GetCell(x, y);
}
}
}
public Cell GetCell(int x, int y)
{
return new Cell(x, y);
}
public void Copy(IMap<Cell> sourceMap)
{
// ...
}
public override string ToString()
{
var sb = new StringBuilder();
foreach (var cell in GetAllCells())
{
sb.Append(cell.ToString());
}
return sb.ToString();
}
}
public interface IMap<T> where T : ICell
{
int Width { get; }
int Height { get; }
IEnumerable<T> GetAllCells();
T GetCell(int x, int y);
void Copy(IMap<T> sourceMap);
}
public class Cell : ICell
{
public int X { get; }
public int Y { get; }
public Cell(int x, int y)
{
X = x;
Y = Y;
}
public override string ToString()
{
return "overloaded";
}
}
public interface ICell
{
int X { get; }
int Y { get; }
}
public class FieldOfView
{
private readonly IMap<ICell> _map;
public FieldOfView(IMap<ICell> map)
{
_map = map;
}
public void DoStuff()
{
foreach (var cell in _map.GetAllCells())
{
// ...
}
}
}

这与这个堆栈溢出问题类似,但有点不同。我尝试实现接口IMapIMap<T> : IMap where T : ICell,但也遇到了问题。

最后,我不确定这是否可以通过协变/逆变来解决,但我使用的是C#3.0,所以这对我来说是不可能的(除非切换版本是唯一的方法)。


我认为用隐式/直接演员阵容可以吗?

_fieldOfView = new FieldOfView(this as IMap<ICell>); // or
_fieldOfView = new FieldOfView((IMap<ICell>)this);

但如果有更好的方法,我愿意这样做。当我将Map转换为IMap<ICell>时,Resharper确实向我发出了警告:

可疑强制转换:解决方案中没有从MapIMap<ICell>继承的类型

第2版:看起来两个演员阵容都不起作用我决定让Map从IMap派生,只在代码中需要的地方创建Cell对象。

感谢@Rob和@MK87的帮助!

IMap<Cell>而不是IMap<ICell>相同,因此此行:

_fieldOfView = new FieldOfView(this as IMap<ICell>);

将始终传递null作为参数。

,这肯定是可以用方差解决的。

例如,您可以有:

IEnumerable<object> list = new List<string>();

由于listIEnumerable<outT>,这意味着从T导出的每个具有TTIEnumerable<TT>都是list的有效值。因此List不必是object,它可以是任何派生类型。

但因为你不能使用方差,我们需要另一个破解。

可能的解决方案:不是从IMap<Cell>派生Map,而是从IMap<ICell>派生。。您只需要更正一些点,例如GetCell()的返回类型必须变为ICell,而不是Cell。这对你来说可行吗?

最新更新