2014-04-09 26 views
2

我正在制作一个使用数据库的简短程序。我的大多数表格都有一个代表它们的类,通常我通过Id访问此表中的行。所以我认为我会很漂亮,为我的课程创建这个基础类,认为我能够标准化我的方法。我做了这个:替代静态抽象属性进行延迟加载

public abstract class Loadable<T> where T: Loadable<T>, new() 
{ 
    protected abstract static List<T> loaded { get; set;} 
    protected abstract static string tableName { get; set; } 
    protected abstract void setData(DataRow data); 
    public abstract int id { get; set; } 
    public static T getById(int id) 
    { 
     if (loaded.Any((g) => g.id == id)) 
      return (T)loaded.First((g) => g.id == id); 

     T ret = new T(); 
     ret.setData(SQLiteDB.main.getRowById(tableName, id)); 
     T. 
     return ret; 
    } 
} 

当我讲完后,我试着用满意的飘飘然感觉编译只是为了学习抽象静态不是个东西。标准菜鸟错误。更不用说

T.loaded.Add(ret); 

行是只是普通的尴尬。

虽然我可以在每一堂课中找到子弹和实施这种方法,但我想知道你们可以想出什么样的酷酷模式。我研究过一些,但他们大多需要派生类中的实现。

算法的主要方面包括:

  • 只加载一次每个项目。
  • 加载新项目时会填充“已加载”列表
  • 将实现保持在最低限度 - 在这种情况下,它只是“加载”和“tableName”(setData已被要求)。
  • SQLite并不是真正的重点,这个想法是只执行一次重负载。

这是可能的,还是只是一个梦想?

编辑:

我可能会中省略,我想有每个类实例的自己的静态字典(的原因抽象静态)

整点,我想,正在寻找一种在派生类中强制实施静态变量的方法。

+0

我真的不明白什么是打扰你。是不是你不能通过静态属性实现加载? –

+0

@Yuval这是事实,我不能持有对派生类的静态绑定数据的引用。我想,这是设计。 – MHDante

回答

1

我不明白为什么所有这些都必须得到保护或抽象。这是一个简单的例子,我认为,它可以实现您的目标。它会对继承的类进行反射,以查找基类为查找而缓存的静态“TableName”属性。另一种选择是在继承类上使用属性,但是您将需要反射。如果未定义TableName,则会引发异常。此外,我使用ConcurrentDictionary更快速地查找实例的线程安全。

public abstract class Loadable<T> where T: Loadable<T>, new() 
{ 
    private readonly static ConcurrentDictionary<int, T> _cache = new ConcurrentDictionary<int, T>(); 

    private readonly static Func<int, T> _addDelegate = key => { 
     T item = new T(); 
     item.SetData(SQLiteDB.main.getRowById(_tableName, key)); 
     return item; 
    }; 

    private static readonly string _tableName; 

    static Loadable() 
    { 
     var prop = typeof(T).GetProperty("TableName", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); 
     if (prop == null) 
      throw new NotSupportedException(string.Format("Type '{0}' does not support TableName", typeof(T))); 

     _tableName = (string)prop.GetValue(null); 
    } 

    protected abstract void SetData(DataRow data); 

    public virtual int Id { get; set; } 

    public static T GetById(int id) 
    { 
     return _cache.GetOrAdd(id, _addDelegate); 
    } 
} 
+0

啊!辉煌!感谢你,我更了解泛型静态构造函数!这个问题也很有帮助:http://stackoverflow.com/a/2936591/2633114 – MHDante