如果标题含糊不清或重复,我道歉。我今天花了大量时间阅读仿制药,并寻找类似的情况无济于事。
我正在写一个小游戏引擎。这方面的一个方面是“单位”的能力。携带资源。有些单位可以携带任何资源,有些单位只能携带某些专门资源。为此,我有以下结构:
Resource
基类:
public abstract class Resource
{
private int _count;
public int Count
{
get { return _count; }
set { _count = value; }
}
public Resource(int resourceCount)
{
_count = resourceCount;
}
}
然后是Resource
专精Wood
:
public class Wood : Resource
{
public Wood(int resourceCount) : base(resourceCount)
{
}
}
然后我的通用ResourceStore
:
public class ResourceStore<T> : IResourceStore where T : Resource
{
private List<Resource> _store;
public IEnumerable<Resource> Store { get { return _store; } }
public void AddResource(Resource resource)
{
_store = new List<Resource>();
_store.Add(resource);
}
}
最后是一个专门的商店WoodStore
,其中AddResource
方法只接受Wood
:
public class WoodStore : ResourceStore<Wood>
{
}
为了完整性,接口IResourceStore
由可以充当资源存储的任何东西实现:
public interface IResourceStore
{
void AddResource(Resource resource);
}
如果我运行一个小型控制台应用程序并执行以下操作,我会在尝试将Wheat
添加到WoodStore
时出现错误。但事实并非如此,实际上输出显示WoodStore
现在包含木材和小麦。这是控制台应用程序:
class Program
{
static void Main(string[] args)
{
WoodStore store = new WoodStore();
store.AddResource(new Wood(10));
store.AddResource(new Wheat(5));
foreach (Resource resource in store.Store)
{
Console.WriteLine("{0} {1}", resource.GetType(), resource.Count);
}
Console.ReadLine();
}
}
最后这里是Wheat
只是为了完整性,尽管没有什么特别之处:
public class Wheat : Resource
{
public Wheat(int resourceCount) : base(resourceCount)
{
}
}
我显然在这一棵树上咆哮着错误的树,并且对于如何限制WoodStore只接受Wood而感谢任何帮助。最终会有很多不同的商店会有一定的限制,我正在寻找一种方法来处理这个问题。
非常感谢。
答案 0 :(得分:4)
您的界面必须是通用的,您需要在后备存储中使用T
,new List
中的AddResource
也不是我想要的:
public interface IResourceStore<T> where T : Resource
{
void AddResource(T resource);
}
public class ResourceStore<T> : IResourceStore<T> where T : Resource
{
private List<T> _store = new List<T>();
public IEnumerable<T> Store { get { return _store; } }
public void AddResource(T resource)
{
//_store = new List<T>(); //Do you really want to create a new list every time you call AddResource?
_store.Add(resource);
}
}
答案 1 :(得分:0)
首先,正如您在开头所说的那样,标题与问题内容的关联性不是很明显。
哈哈的第一个简单基本答案是多个商店都有限制,即使在允许对资源进行操作的方法中也使用通用过滤器:
public class ResourceStore<T> : IResourceStore where T : Resource
{
private List<T> _store;
public IEnumerable<T> Store { get { return _store; } }
public void AddResource(T resource)
{
_store = new List<T>();
_store.Add(resource);
}
void IResourceStore.AddResource(Resource resource)
{
//possible excepion here for type mismach!
AddResource(resource as T);
}
}
如果你注意到没有明确的可见性应用的另一种方法,
该方法是显式的IResourceStore
接口实现,这是必需的,
但我可以建议不是一个好的设计解决方案。
首先,如果抽象存储的概念是通用的,即使接口应该是通用的,如果您的需求没有明确需要,那么接口应该与抽象类的通用相同通用限制:
public interface IResourceStore<T>
where T : Resource
{
void AddResource(T resource);
}
以相同的方式将可枚举的支持包含在接口中,以便抽象 上课会支持它。所以最终的代码应该类似于:
public class ResourceStore<T> : IResourceStore<T> where T : Resource
{
private List<T> _store;
public IEnumerable<T> Store { get { return _store; } }
public void AddResource(T resource)
{
_store = new List<T> {resource};
}
public IEnumerator<T> GetEnumerator()
{
return Store.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public interface IResourceStore<T> : IEnumerable<T>
where T : Resource
{
void AddResource(T resource);
}
public abstract class Resource
{
public int Count { get; set; }
protected Resource(int resourceCount)
{
Count = resourceCount;
}
}
希望这会有所帮助。 我还应用了一些小代码优化。