限制generics子类方法在c#中可以接受的类型

如果标题含糊不清或者这是重复,我会道歉。 我今天花了很多钱阅读仿制药,并寻找类似的情况无济于事。

我正在写一个小游戏引擎。 其中一个方面是“单位”携带资源的能力。 有些单位可以携带任何资源,有些单位只能携带某些专门资源。 为此,我有以下结构:

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 : IResourceStore where T : Resource { private List _store; public IEnumerable Store { get { return _store; } } public void AddResource(Resource resource) { _store = new List(); _store.Add(resource); } } 

最后是一个专门的商店WoodStore ,其中AddResource方法应该只接受Wood

 public class WoodStore : ResourceStore { } 

为了完整性,接口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。 最终会有很多不同的商店会有一定的限制,我正在寻找一种方法来处理这个问题。

非常感谢。

您的界面需要是通用的,您需要在后备存储中使用TAddResourcenew List也不是您想要的我打赌:

 public interface IResourceStore where T : Resource { void AddResource(T resource); } public class ResourceStore : IResourceStore where T : Resource { private List _store = new List(); public IEnumerable Store { get { return _store; } } public void AddResource(T resource) { //_store = new List(); //Do you really want to create a new list every time you call AddResource? _store.Add(resource); } } 

首先,正如你在开头所说的那样,标题与问题内容的关系并不那么明确。

哈哈的第一个简单基本答案是多个商店都有限制,即使在允许操作资源的方法中也使用通用filter

 public class ResourceStore : IResourceStore where T : Resource { private List _store; public IEnumerable Store { get { return _store; } } public void AddResource(T resource) { _store = new List(); _store.Add(resource); } void IResourceStore.AddResource(Resource resource) { //possible excepion here for type mismach! AddResource(resource as T); } } 

如果你注意到没有显式可见性应用程序的另一种方法,该方法是显式的IResourceStore接口实现,这是必需的,但我可以建议不是一个好的设计解决方案。

首先,如果抽象存储的概念是通用的,即使接口应该是通用的,如果您的需求没有明确需要,那么接口应该是具有通用限制的抽象类的相同generics:

 public interface IResourceStore where T : Resource { void AddResource(T resource); } 

以同样的方式,可枚举的支持应包含在接口中,以便抽象类支持它。 所以最终的代码应该类似于:

 public class ResourceStore : IResourceStore where T : Resource { private List _store; public IEnumerable Store { get { return _store; } } public void AddResource(T resource) { _store = new List {resource}; } public IEnumerator GetEnumerator() { return Store.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public interface IResourceStore : IEnumerable where T : Resource { void AddResource(T resource); } public abstract class Resource { public int Count { get; set; } protected Resource(int resourceCount) { Count = resourceCount; } } 

希望这可以帮助。 我还应用了一些小代码优化。