2014-12-04 63 views
6

我有很多方法在大部分的後面跟着相同的算法,我理想地希望能夠調用一個消除大量代碼重複的泛型方法。有大量代碼重複的問題

我有一大堆像下面的那些方法,我會最佳希望能夠只是調用 Save<SQLiteLocation>(itemToSave);我卻帶來很大的麻煩,因爲這些方法 SQLiteConnection.Find<T>不會接受如T抽象數據類型在泛型中。

有什麼辦法來解決這個問題,如果我能得到它固定的,我會保存代碼多達150線

這裏是我的代碼:

public bool SaveLocation(ILocation location, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection (dbPath); 

     SQLiteLocation itemToSave = new SQLiteLocation(); 
     itemToSave.LocationName = location.LocationName; 
     itemToSave.Latitude = location.Latitude; 
     itemToSave.Longitude = location.Longitude; 
     itemToSave.PrimaryKey = location.PrimaryKey; 

    ---------------------------------------------------------------------------------------- 

     SQLiteLocation storedLocation = dbConn.Find<SQLiteLocation> 
             (x => x.PrimaryKey == location.PrimaryKey); 

     if (storedLocation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 

     else if (storedLocation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 

這裏的另一種方法怎麼看在我的虛線下面兩種方法的代碼基本上

public bool SaveInvitation(IInvitation invitation, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     SQLiteInvitation itemToSave = new SQLiteInvitation(); 
     itemToSave.GroupName = invitation.GroupName; 
     itemToSave.InviterName = invitation.InviterName; 
     itemToSave.ParseID = invitation.ParseID; 
     itemToSave.GroupParseID = invitation.GroupParseID; 
     itemToSave.PrimaryKey = invitation.PrimaryKey; 

--------------------------------------------------------------------------------------- 

     SQLiteInvitation storedInvitation = dbConn.Find<SQLiteInvitation> 
              (x => x.PrimaryKey == invitation.PrimaryKey); 

     if (storedInvitation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 
     else if (storedInvitation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 
+0

您可以使用AutoMapper或類似的東西來移動性能。另外,如果您將'itemToSave'移出方法並將其作爲參數傳遞,那麼我相信您可以使其他代碼通用。 – 2014-12-04 20:01:28

+0

您是否考慮過尋找表達式樹來構建「查找」聲明? – 2014-12-04 20:02:23

+0

'storedX'或者是null,所以不需要使用else if。由於這個原因,你永遠不會返回false,所以你可以刪除返回值。左邊是'if(storedX!= null){dbConn.Update(itemToSave); } else {dbConn.Insert(itemToSave); primaryKey = itemToSave.PrimaryKey; }'。刪除了3行 – Default 2014-12-04 20:17:21

回答

0

出於某種原因,引發了不支持的異常 當我用:

T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

下面的代碼固定我的困境雖然,謝謝大家的幫助,我喜歡這個網站! 此外,我增加了一個限制對T看到爲T必須是一個非抽象類和接口僅僅是我想

private void SaveItem<T>(T item, ref int primaryKey) 
     where T : ISQLiteClass, new() 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     T storedItem = dbConn.Find<T>(primaryKey); 

     if (storedItem != null) 
     { 
      dbConn.Update(item); 
     } 
     else if (storedItem == null) 
     { 
      dbConn.Insert(item); 
      primaryKey = item.PrimaryKey; 
     } 
    } 
1

你不應該能夠做這樣的事同樣的事情: 注:ICOMM onInterface是你希望用作T的任何允許類之間通用的任何東西。最好查看你的代碼,暴露PrimaryKey屬性的接口或類。

public bool SaveItem<T>(T item, ref int primaryKey) where T : ICommonInterface, new() 
{ 
    var dbConn = new SQLiteConnection(dbPath); 


    T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

    if (storedItem != null) 
    { 
     dbConn.Update(item); 
     return true; 
    } 
    else if (storedItem == null) 
    { 
     dbConn.Insert(item); 
     primaryKey = item.PrimaryKey; 
     return true; 
    } 
    return false; 
} 

編輯:添加新的()約束的方法。

+0

你是正確的這固定我的代碼,你保存了我的許多行代碼 – Guano 2014-12-04 21:28:02

+0

其實它看起來我太過皮疹,我得到這個錯誤:\t \t \t'T '必須是具有公共無參數構造函數的非抽象類型,才能將其用作通用類型或方法'SQLite'中的參數'SQLite.SQLiteConnection.Find (System.Linq.Expressions.Expression > )'(CS0310)(ShoppingAssistant) – Guano 2014-12-04 22:13:01

+0

查看修改後的答案。爲該方法添加一個新的()約束。 ex:where T:ICommonInterface,new() – gmiley 2014-12-05 12:20:09