2010-03-31 62 views
1

我所有的東西我一直在嘗試做一段時間,還沒有找到一個好的策略來做到這一點,我不知道C#甚至可以支持我想要做的事情。C#尋找新工具的工具箱,如何模板這個代碼

示例想象一個像這樣的模板,在管理代碼中重複遍歷cocept函數返回由成功標誌和錯誤列表組成的結果。

 public Result<Boolean> RemoveLocation(LocationKey key) 
     { 
      List<Error> errorList = new List<Error>(); 
      Boolean result = null; 
      try{ 
       result = locationDAO.RemoveLocation(key); 
      }catch(UpdateException ue){ 
       //Error happened less pass this back to the user! 
       errorList = ue.ErrorList; 
      } 

      return new Result<Boolean>(result, errorList); 
     } 

展望變成下面那裏做類似的模板是一些電話(最好不是靜態的),它返回一個布爾值。我知道我可以在堆棧的意義上做到這一點,但我真的想通過對象引用來做到這一點。

 public Result<Boolean> RemoveLocation(LocationKey key) 
     { 
      var magic = locationDAO.RemoveLocation(key); 

      return ProtectedDAOCall(magic); 
     } 
     public Result<Boolean> CreateLocation(LocationKey key) 
     { 
      var magic = locationDAO.CreateLocation(key); 

      return ProtectedDAOCall(magic); 
     } 


     public Result<Boolean> ProtectedDAOCall(Func<..., bool> doSomething) 
     { 
      List<Error> errorList = new List<Error>(); 
      Boolean result = null; 
      try{ 
       result = doSomething(); 
      }catch(UpdateException ue){ 
       //Error happened less pass this back to the user! 
       errorList = ue.ErrorList; 
      } 

      return new Result<Boolean>(result, errorList); 
     } 

如果有任何更多的信息,你可能需要告訴我。

我很想看看別人能想出什麼。


馬克的解決方案應用到上面的代碼

public Result<Boolean> CreateLocation(LocationKey key) 
    { 
     LocationDAO locationDAO = new LocationDAO(); 
     return WrapMethod(() => locationDAO.CreateLocation(key)); 
    } 


    public Result<Boolean> RemoveLocation(LocationKey key) 
    { 
     LocationDAO locationDAO = new LocationDAO(); 
     return WrapMethod(() => locationDAO.RemoveLocation(key)); 
    } 


    static Result<T> WrapMethod<T>(Func<Result<T>> func) 
    { 
     try 
     { 
      return func(); 
     } 
     catch (UpdateException ue) 
     { 
      return new Result<T>(default(T), ue.Errors); 
     } 
    } 
+2

我不喜歡那個異常包裝的外觀,順便說一句。例外*已經*氣泡和結果*已經*返回。你不需要爲此創造一個新的隱喻。 – 2010-03-31 16:04:23

+0

這是一個例子,這個想法是我需要的。有更多的修剪邏輯繼續清理最終暴露給用戶的異常。 – Nix 2010-03-31 16:44:37

+0

我建議將'LocationDAO locationDAO = new LocationDAO();'移動到WrapMethod。請看下面 – vittore 2010-03-31 18:57:27

回答

1

喜歡的東西:

public Result<Boolean> RemoveLocation(LocationKey key) 
{ 
    return WrapMethod(() => locationDAO.RemoveLocation(key)); 
} 
static Result<T> WrapMethod<T>(Func<T> func) { 
    try 
    { 
     return new Result<T>(func()); 
    } 
    catch (SomeExceptionBase ex) 
    { 
     return new Result<T>(ex.ErrorList); 
    } 
    catch (Exception ex) 
    { 
     return new Result<T>((List<Error>)null); 
    } 
} 

和(如圖所示最小值)

class Result<T> 
{ 
    private Result(bool isError, T value, List<Error> erors) { } 
    public Result(T value) : this(false, value, null){ } 
    public Result(List<Error> errors) : this(true, default(T), errors) { } 
} 
class SomeExceptionBase : Exception 
{ 
    public List<Error> ErrorList { get; private set; } 
} 

(儘管如果我要做到這一點,我可能會做一些更有趣與不發生異常是SomeExceptionBase

+0

仍在測試出來,但有一些小的teaks WrapMethod簽名應該是結果(你可能要編輯) WrapMethod (Func鍵> FUNC){ 感謝。一旦我確認了所有功能,我將標記。 – Nix 2010-03-31 16:35:25

+0

@Nix - 我不確信,你知道。 '功能'工作正常...?這有點重要,不是嗎?要轉變「返回」bool「的東西(即'功能'變成'結果'? – 2010-03-31 16:44:06

+0

我認爲誤解是道返回結果 Nix 2010-03-31 16:47:43

0

我們有以下在我們的項目,它看起來非常相似

 public TResult DoCall<TResult,TProvider>(Func<TProvider, TResult> action) where TProvider : class, IProvider 
     { 
      TResult ret = default(TResult); 
      try 
      { 
       var prov = (TProvider) ModelManagerProvider.GetProviderByType(typeof(TProvider)); 
       ret = action(prov); 
      } 
      catch (Exception ex) 
      { 
       ThrowErrorTool.ThrowError(ex); 
      } 
      return ret; 
     } 

,這裏是我們如何把它

 public bool UpdateAdverseEventSection(AdverseEventsDTO aeDTO) 
     { 
      return DoCall((AdverseEventsProvider r) => r.UpdateAdverseEventSection(aeDTO)); 
     } 
+0

對不起,我認爲這有點太過分了,但它是一個很好的例子,如果你可以使它更通用,它會幫助...我不需要的是TProvider的概念(在我們的代碼中)。我只是想執行一些操作,不需要通過它。 你的是更通用的,然後我需要。 – Nix 2010-03-31 16:39:22

0
static Result<T> WrapMethod<T>(Func<LocationDao, Result<T>> func) 
{ 
    try 
    { 
     var l = new LocationDao(); 
     return func(l); 
    } 
    catch (UpdateException ue) 
    { 
     return new Result<T>(default(T), ue.Errors); 
    } 
} 
public Result<Boolean> RemoveLocation(LocationKey key)  
{     
    return WrapMethod((l) => l.RemoveLocation(key));  
} 
+0

問題是它不會總是位置,它可能是另一種類型..... – Nix 2010-03-31 19:08:07

+0

這就是爲什麼我們在我們的例子中有TProvider – vittore 2010-03-31 19:27:16