C# 分解函数的正确方法

C# 分解函数的正确方法,c#,function,C#,Function,我有一个大物体,在我用它做一些事情之前,我需要检查多个条件。我有一个很大的功能。它是不可读的,我想把它分解成更小的函数,使我的代码更清晰 函数正在检查条件,如果有不正确的地方,它将停止并返回问题(属于enum类型) 看起来是这样的: AnswerEnum CheckEverything(Bigobj o) { // some calculation if (...) return AnswerEnum.Error1; // some more calculation

我有一个大物体,在我用它做一些事情之前,我需要检查多个条件。我有一个很大的功能。它是不可读的,我想把它分解成更小的函数,使我的代码更清晰

函数正在检查条件,如果有不正确的地方,它将停止并返回问题(属于
enum
类型)

看起来是这样的:

AnswerEnum CheckEverything(Bigobj o)
{
  // some calculation 
  if (...)
   return AnswerEnum.Error1;

  // some more calculation 
  if (...)
   return AnswerEnum.Error2;

  ... 
  return AnswerEnum.OK;
}
List<Func<Bigobj, AnswerEnum>> list;
现在,我想用更小的函数进行计算,我能做的是:

AnswerEnum CheckEverything(Bigobj o)
    { 
    AnswerEnum ret;
    ret=CheckFirstThing(o);
      if (ret!=AnswerEnum.OK)
       return ret;

    ret=CheckSecondThing(o);
      if (ret!=AnswerEnum.OK)
       return ret;

      ... 
      return AnswerEnum.OK;
    }
此解决方案包含

if (ret!=AnswerEnum.OK)
   return ret;
好几次了,我不喜欢。
我希望尽量减少
return
语句和代码的任何重复部分的数量。在这种情况下,我该怎么做呢?

IMHO,当要执行许多检查时,最好使用
委托字典设计模式(
):

AnswerEnum CheckEverything(Bigobj o)
{ 
   List<Func<AnswerEnum>> checkings = new List<Func<AnswerEnum>>
   {
     (obj)=>{return CheckFirstThing(obj);},
     (obj)=>{return CheckSecondThing(obj);}
   };

   foreach(var chk in checkings)
   {
      AnswerEnum answer;
      if((answer= chk(o))!=AnswerEnum.OK)
            return answer;
   }
   return AnswerEnum.OK;
}
AnswerEnum CheckEverything(Bigobj o)
{ 
列表检查=新列表
{
(obj)=>{返回CheckFirstThing(obj);},
(obj)=>{返回CheckSecondThing(obj);}
};
foreach(检查中的var chk)
{
回答;回答;
如果((答案=chk(o))!=AnswerEnum.OK)
返回答案;
}
返回AnswerEnum.OK;
}

IMHO,在执行许多检查时,最好使用
委托字典设计模式
():

AnswerEnum CheckEverything(Bigobj o)
{ 
   List<Func<AnswerEnum>> checkings = new List<Func<AnswerEnum>>
   {
     (obj)=>{return CheckFirstThing(obj);},
     (obj)=>{return CheckSecondThing(obj);}
   };

   foreach(var chk in checkings)
   {
      AnswerEnum answer;
      if((answer= chk(o))!=AnswerEnum.OK)
            return answer;
   }
   return AnswerEnum.OK;
}
AnswerEnum CheckEverything(Bigobj o)
{ 
列表检查=新列表
{
(obj)=>{返回CheckFirstThing(obj);},
(obj)=>{返回CheckSecondThing(obj);}
};
foreach(检查中的var chk)
{
回答;回答;
如果((答案=chk(o))!=AnswerEnum.OK)
返回答案;
}
返回AnswerEnum.OK;
}

如果您所有的检查函数都有相同的签名(您发布的代码中似乎就是这样),那么您所要做的就是创建一个代理列表,如下所示:

AnswerEnum CheckEverything(Bigobj o)
{
  // some calculation 
  if (...)
   return AnswerEnum.Error1;

  // some more calculation 
  if (...)
   return AnswerEnum.Error2;

  ... 
  return AnswerEnum.OK;
}
List<Func<Bigobj, AnswerEnum>> list;
最后,检查一切:

AnswerEnum ret;

foreach(Func<Bigobj, AnswerEnum> f in list)
{
    ret = f(o);
    if (ret != AnswerEnum.Ok) return ret;
}
return AnswerEnum.Ok;
AnswerEnum-ret;
foreach(列表中的函数f)
{
ret=f(o);
如果(ret!=AnswerEnum.Ok)返回ret;
}
返回AnswerEnum.Ok;

如果您所有的检查函数都有相同的签名(您发布的代码中似乎就是这样),那么您所要做的就是创建一个代理列表,如下所示:

AnswerEnum CheckEverything(Bigobj o)
{
  // some calculation 
  if (...)
   return AnswerEnum.Error1;

  // some more calculation 
  if (...)
   return AnswerEnum.Error2;

  ... 
  return AnswerEnum.OK;
}
List<Func<Bigobj, AnswerEnum>> list;
最后,检查一切:

AnswerEnum ret;

foreach(Func<Bigobj, AnswerEnum> f in list)
{
    ret = f(o);
    if (ret != AnswerEnum.Ok) return ret;
}
return AnswerEnum.Ok;
AnswerEnum-ret;
foreach(列表中的函数f)
{
ret=f(o);
如果(ret!=AnswerEnum.Ok)返回ret;
}
返回AnswerEnum.Ok;
定义一种新方法:

private AnswerEnum ConditionalCheck(AnswerEnum current, 
                                    Func<BigObj, AnswerEnum> func,
                                    BigObj obj)
{
    return current == AnswerEnum.OK ? func(obj) : current;
}
或者,如果您真的想减小方法的大小,我会将其更改为:

AnswerEnum CheckEverything(List<Func<BigObj, AnswerEnum> funcs, Bigobj o)
{
    foreach (var func in funcs)
    {
        var result = func(o);
        if (result != AnswerEnum.OK) { return result; }
    }
    return AnswerEnum.OK;
}
AnswerEnum CheckEverything(列表定义新方法:

private AnswerEnum ConditionalCheck(AnswerEnum current, 
                                    Func<BigObj, AnswerEnum> func,
                                    BigObj obj)
{
    return current == AnswerEnum.OK ? func(obj) : current;
}
或者,如果您真的想减小方法的大小,我会将其更改为:

AnswerEnum CheckEverything(List<Func<BigObj, AnswerEnum> funcs, Bigobj o)
{
    foreach (var func in funcs)
    {
        var result = func(o);
        if (result != AnswerEnum.OK) { return result; }
    }
    return AnswerEnum.OK;
}

AnswerEnum检查所有内容(ListHead to Head to我会选择这个解决方案,尼斯。这里没有真正的理由在循环外部定义
ret
。它可能应该在循环内部确定范围。我会选择这个解决方案,尼斯。没有真正的理由在循环外部定义
ret
。它可能应该在循环内部确定范围哦,谢谢你的回答!它清晰易读,但我不喜欢一件事:在发现问题后,我不想调用其他函数,即使它们什么也不做。谢谢你的回答!它清晰易读,但我不喜欢一件事:在发现问题后,我不想调用其他函数,即使它们不会执行任何操作什么都没有。