我正在为一个roguelike编程一个地牢生成器。我有一个名为Room
的基类。它包含可由其他类型的房间继承的方法。它看起来像这样,但后来更先进
class Room
{
protected virtual void Construct() { /*make square room here*/ }
}
class RoundRoom : Room
{
protected override void Construct() { /*make round room here*/ }
}
我的课堂产生房间需要“喂养”房间来生成。房间处理建筑,我有不同类型的房间。我希望它可以根据某些条件或机会生成某些特定的房间。
所以我用不同类型的房间喂它。首先我想到了这个:
class RoomEntry
{
public Point chance;
public Room room;
}
然后有一个数组
RoomEntry[] entries;
然后只是喂它
Generator.Feed(entries[random.Next(0, 10)].room); // just an example
但那不行!如果我在生成器中编辑房间,它也将在RoomEntry
中更改!而且我需要使用它好几次!
所以,如果我根据某些房间类型制作新房间......它会工作!
所以我想出了这个:
class RoomPlanner
{
class RoomEntry<T> where T : Room, new()
{
public Point chance;
T r;
public Room RoomToBuild()
{
return new T();
}
}
RoomEntry<Room>[] entrys;
public void Foo()
{
entrys = new RoomEntry<Room>[10];
for (int i = 0; i < entrys.Length; i++)
{
entrys[i] = new RoomEntry<RoundRoom>();
}
}
}
但那是不可能的。我收到了这个错误:
Cannot implicitly convert type 'Super_ForeverAloneInThaDungeon.RoomPlanner.RoomEntry<Super_ForeverAloneInThaDungeon.RoundRoom>' to 'Super_ForeverAloneInThaDungeon.RoomPlanner.RoomEntry<Super_ForeverAloneInThaDungeon.Room>'
那么,我怎样才能让它接受从Room
继承的类,或者我如何采用不同的方法解决这个问题呢?
这不是this的副本。这是一个不同的问题,我没有足够的信息来完全解决我的问题。
答案 0 :(得分:3)
问题是协变/逆变类型参数只能与接口或委托类型一起使用。 (this MSDN article中有关此内容的详细信息。)基本上,即使约束为RoomEntry<T>
,也无法声明与RoomEntry<Room>
具有逆差的T : room
。
您可以通过定义由IRoomEntry
实现的RoomEntry<T>
接口来解决这个问题,如下所示:
interface IRoomEntry
{
Room RoomToBuild();
}
class RoomPlanner
{
class RoomEntry<T> : IRoomEntry
where T : Room, new()
{
public Point chance;
T r;
public Room RoomToBuild()
{
return new T();
}
}
IRoomEntry[] entrys;
public void Foo()
{
entrys = new IRoomEntry[10];
for (int i = 0; i < entrys.Length; i++)
{
entrys[i] = new RoomEntry<RoundRoom>();
}
}
}
答案 1 :(得分:1)
好像你只想Clone
房间,然后再把它送到Generator
。您只需在Clone
课程中添加Room
方法:
Room Clone() { return (Room)this.MemberwiseClone(); }
然后像这样喂它:
Generator.Feed(entries[random.Next(0, 10)].room.Clone());