我如何使这个ImageList类通用,以便它可以使用任何资源?

时间:2011-10-26 11:31:59

标签: c# generics

对于我的游戏,我正在创建一个资源类,管理器资源喜欢纹理,声音,字体等。我制作了这个ImageList类,它在运行时根据需要自动加载纹理。

class TextureList
{
    private Dictionary<string, Texture> _list;

    public Texture this[string name]
    {
        get
        {
            Texture tex;
            bool success = List.TryGetValue(name, out tex);

            if (!success)
            {
                tex = Resources.LoadImage(name);
                List[name] = tex;
            }

            return tex;
        }
    }

    protected Dictionary<String, Texture> List
    {
        get
        {
            return _list ?? new Dictionary<String, Texture>();
        }
    }
}

现在我想使这个类变得通用,这样我就可以创建一个FontList或SoundList类,而无需将每个纹理更改为Sound或Font(以及编写大量重复代码)。有谁愿意帮我制作一个通用版本?

2 个答案:

答案 0 :(得分:7)

  1. 让您的班级通用
  2. 在构造函数中,您必须传递一个Func,其中T是您的通用参数。
  3. 逻辑:当你没有找到该项时,调用传入的Func并将结果存储在内部列表中。
  4. 所以,你的班级变成了

    var x = new Cachinglist<Texture>(s => Resources.LoadImage(s));
    

    class CachingList<T>
    {
        private readonly Dictionary<string, T> _list = new Blabla..();
        private readonly Func<string,T> _itemsFactory;
    
        public CachingList(Func<string,T> itemsFactory) {
          _itemsFactory = itemsFactory;
        }
    
        public T this[string name]
        {
            get
            {
                T t;
    
                if (!_list.TryGetValue(name, out t))
                {
                    t = _itemsFactory(name);
                    _list[name] = t;
                }
    
                return t;
            }
        }
    }
    

答案 1 :(得分:6)

假设你的纹理,声音等都有一个共同的基类(我将在本例中将其称为BaseResource),创建一个具有加载器的通用基类。

public abstract class ResourceList<TYPE> where TYPE : BaseResource // change to your actual base-class or interface
{
    private Dictionary<string, TYPE> resources_ = new Dictionary<string, TYPE>();

    // loader
    protected abstract TYPE LoadImpl(string name);

    public TYPE this[string name]
    {
        get
        {
            TYPE resource;
            if(!resources_.ContainsKey(name))
            {
                resource = LoadImpl();
                resources_[name] = resource;
            }
            else
                resource = resources_[name];

            return resource;
        }
    }
} // eo class ResourceList

现在,为不同的资源提供具体的实现:

public class TextureList : ResourceList<Texture>
{
    protected override Texture LoadImpl(string name)
    {
        return Resources.LoadImage(name);
    }
}

也许你的声音看起来像这样:

public class SoundList : ResourceList<Sound>
{
    protected override Sound LoadImpl(string name)
    {
         return Resources.LoadSound(name);
    }
}