C#搜索工具箱的新工具,如何模板化这段代码

时间:2010-03-31 15:53:56

标签: c# algorithm refactoring

我有一段时间我一直试图做的事情并且尚未找到一个好的策略来做到这一点,我不确定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);
        }

希望将其转换为如下所示的模板,其中Do Something是一些返回布尔值的调用(最好不是静态的)。我知道我可以在堆栈意义上做到这一点,但我真的想通过对象引用来做到这一点。

        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);
        }

如果您需要更多信息,请告知我们。

我很想知道其他人能想出什么。


应用于上述代码的Marc解决方案

    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);
        }
    }

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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));
        } 

答案 2 :(得分: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));     
}