2014-04-09 27 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