干修复可能性,C#

时间:2016-03-21 20:19:42

标签: c# .net

这段代码一直困扰着我,部分是因为

if (result != OpResult.Success) { // return

代码在任何地方重复出现。

执行一系列(1..n)评估。每次评估后,都会进行检查以确保操作成功(使用从枚举派生的自定义返回值):OpResult.Success

这是一个例子(带有示例对象等):

OpResult result = OpResult.Sucess;

result = performOperationOne(commonObjectArgument);

if (result != OpResult.Success)
{
    trace.Exit(); // Exit logging mechanism
    return result;
}

result = performOperationTwo(commonObjectArgument);

if (result != OpResult.Success)
{
    trace.Exit();
    return result;
}

如您所见,if (result != OpResult.Success)用作流量控制,即除非所有先前的操作都成功,否则下一个操作将不会运行。

使用.Net 4. *,C#在语法上已经变得非常令人难以置信。我可以采取哪些措施来消除每次操作后需要重新编写此评估的内容吗?

5 个答案:

答案 0 :(得分:8)

一种可能性是建立一个操作列表并在循环中执行它们:

var operations = new List<Func<CommonObjectArgumentType, OpResult>>
{
    Operation1,
    Operation2
};

OpResult result = OpResult.Success;
foreach (var op in operations)
{
    result = op(commonObjectArgument);
    if (result != OpResult.Success)
    {
        trace.exit();
        return result;
    }
}

// all operations were successful

答案 1 :(得分:5)

如果签名是相同的,如示例代码所示,您可以在循环中执行这些函数:

// create a collection of your functions where `object` is your argument type
var functions = new Func<object, OpResult>[] {
    performOperationOne,
    performOperationTwo,
    /* etc... */
};

var result = OpResult.Success;

foreach(var function in functions)
{
    result = function(commonObjectArgument);
    if (result != OpResult.Success)
    {
        trace.Exit(); // Exit logging mechanism
        break;
    }
}

return result;

这样,所有状态检查都在同一个地方完成。

Func<上查看>T, TResultMSDN

答案 2 :(得分:1)

如果您不想更改方法,可以尝试对函数调用进行排列,以便您可以...

var success 
  ( doFunctionOne() == OpResult.Success ) &&
  ( doFunctionTwo() == OpResult.Success ) &&
  ( doFunctionThree() == OpResult.Success );

......或者那种效果。它会短路,以便后续的doFunctionX调用在其中一个失败后不会执行。

答案 3 :(得分:0)

由于您询问了花哨的语​​法,您可以使用LINQ to Objects

var operations = new List<Func<object, OpResult>> {
    performOperationOne,
    performOperationTwo,
    // ...
};

var failures = from operation in operations
               let result = operation(commonObjectArgument)
               where result != OpResult.Success
               select result;

// `failures` is lazy-evaluated, so nothing will be executed until we begin this loop
foreach (var failure in failures) {
    trace.Exit();
    return failure;
}

// If we reach this point, we know there were no non-`Success` results

答案 4 :(得分:-1)

从编码标准的角度来看,多次退货通常是不受欢迎的。应该为结果赋值,并在方法结束时返回。跟踪机制可能只能在结束时被调用一次,无论是有条件的还是有条件的(取决于上面的逻辑)。这是一个以更好的方式编写代码的问题。如果不了解跟踪功能,那么就不可能就其使用方法提出最佳方法。无论如何,它应该在方法结束时与返回的值一起实现。

你不需要一个花哨的语法解决方案。只是简单的旧编码实践:)