我正在制作一个使用数据库的短程序。我的大多数表都有一个代表它们的类,通常我会通过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);
线条只是简单的尴尬。
虽然我可能会在每个班级中找到灵感并实施这种方法,但我想知道你们可以提出什么样的酷炫模式。我已经研究了一些,但它们大多需要在派生类中实现。
算法的关键方面包括:
这可能,还是只是一个白日梦?
修改:
我可能已经遗漏了我希望每个Class都有自己的静态实例字典。(抽象静态的原因)
我想,整个观点是寻找一种在派生类中强制执行静态变量的方法。
答案 0 :(得分:1)
我不明白为什么所有这些都必须受到保护或抽象。这是一个简单的例子,我认为,它实现了你的目标。它对继承的类进行反射,以找到静态的&#34; TableName&#34;基类缓存查找的属性。另一种选择是在继承的类上使用属性,但无论哪种方式都需要反射。如果未定义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);
}
}