Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
代码重构c#围绕几个执行相同检查的if语句提问_C#_.net_Asp.net Mvc_Refactoring - Fatal编程技术网

代码重构c#围绕几个执行相同检查的if语句提问

代码重构c#围绕几个执行相同检查的if语句提问,c#,.net,asp.net-mvc,refactoring,C#,.net,Asp.net Mvc,Refactoring,我有一个方法,其中包含大量的if语句,这似乎有点愚蠢,尽管我不确定如何改进代码 这里有一个例子。这个逻辑在控制器中的视图中,现在更好了,但是是否有我遗漏的东西,可能是一个设计模式,阻止我检查panelCount

我有一个方法,其中包含大量的if语句,这似乎有点愚蠢,尽管我不确定如何改进代码

这里有一个例子。这个逻辑在控制器中的视图中,现在更好了,但是是否有我遗漏的东西,可能是一个设计模式,阻止我检查panelCount 非常感谢

if (model.Train && panelCount < NumberOfPanelsToShow)
{
    panelTypeList.Add(TheType.Train);
    panelCount++;
}
if (model.Car && panelCount < NumberOfPanelsToShow)
{
    panelTypeList.Add(TheType.Car);
    panelCount++;
}
if (model.Hotel && panelCount < NumberOfPanelsToShow)
{
    panelTypeList.Add(TheType.Hotel);
    panelCount++;
}
...
if(model.Train&&panelCount
不确定您将此设计模式称为什么。但我曾经读到,每当你发现自己在为不同类型重复代码块时(就像你正在做的那样),你最好把这个功能放到对象本身中去

你可以这样把它打破:

private const NumberOfPanelsToShow = 4;
private int panelCount = 0;

private void addToPanel(IPanelAddable element, PanelList panelTypeList) {
  if(panelCount < NumberofPanelsToShow) {
    element.addToPanelTypeList(panelTypeList);
    panelCount++;
  }
}
实际上,您希望避免上述情况,简化上述/w基类,等等。。。。然后,您的TheType.*对象显然需要实现“addToPanelTypeList”方法:


您可以使用接口或继承来实现相同的目标…

我可能要做的是在模型上设置一个要切换的枚举类型

if(panelCount < NumberOfPanelsToShow)
{
  switch(model.modelType)
  {
   case Model.Car:
    // do stuff
  break;
  }
  panelCount++;
}
if(panelCount
不过,我们需要更多的信息来确定如何处理这些案例,以及在任何给定时间可以应用多少条件

更新


考虑到您提供的其他信息,这里的一些其他答案似乎更合适。考虑到您当前的情况,这个答案是不够的。

通常重构的方法是多态性地进行重构,并负责决定如何处理对象,但由于您的决定基于同一对象的不同方面,我不确定您是否可以在这里这样做

我很想重构成一个方法:

public AddIfSpace(bool thingToTest, TheType typeToAdd, ref currentCount)
{
    if (currentCount<NumberOfPanelsToShow && thingToTest)
    {
     panelTypeList.Add(typeToAdd);
     currentCount++;
    }
}
根据变量的作用域,您可能需要更少或更多的参数,如果panelTypeList类型的作用域受到限制,您可以将其作为panelTypeList类型的扩展方法,这样您就可以得到如下结果:

panelTypeList.AddIfSpace(model.Car,TheType.Car,ref panelCount);
panelTypeList.AddIfSpace(model.Train,TheType.Train,ref panelCount);
panelTypeList.AddIfSpace(model.Hotel,TheType.Hotel,ref panelCount);

这至少避免了代码中重复的逻辑,意味着如果您想更改检查的工作方式,并且如果您很好地命名了方法,您可以在一个地方进行修改,这应该传达意图并使代码更具可读性。

现在没有VS来测试编译代码,但这应该传达逻辑。 您可以使用尽可能多的类型构建数组列表,而不必使用大的if-else或switch语句重复测试逻辑

    TheType[] typesWithPanel = new TheType[] { TheType.Train, TheType.Car, TheType.Hotel};
    if (typesWithPanel.Contains(model.ModelType) && panelCount < NumberOfPanelsToShow)
    {
        panelTypeList.Add(model.ModelType);
        panelCount++;
    }
type[]typesWithPanel=new TheType[]{type.Train,type.Car,type.Hotel};
if(typesWithPanel.Contains(model.ModelType)&&panelCount
假设Model.Train、Model.Car、Model.Plane只是“Model”类型的布尔指示器(而不是创建Train:Model、Plane:Model等)

在你的测试中:

if(panelCount < NumberOfPanelsToShow)
switch (Model.ModelType)
{
    case ModelType.Train :
        ...
        break;

    case ModelType.Plane :
...
}
if(panelCount
然而,由于Car、PLane和Train是不同的,所以您确实应该有一个基本类型模型,从模型中派生Car、PLane和Train,然后您可以重载方法来处理每种类型

if (panelCount < NumberOfPanelsToShow)
{
    panelCount += AddModel(model);
}

private int AddModel(Plane model)
{ // do plane stuff here and on success return 1 else 0; }

private int AddModel(Train model)
{ // do train stuff here and on success return 1 else 0; }

private int AddModel(Car model)
{ // do car stuff here and on success return 1 else 0; }
if(panelCount
我想尝试一下,做一些假设

看起来您有某种“Panel”类,试图用数据模型对象(汽车、酒店、火车等)的信息填充该类。取而代之的是,为什么不使用带有多态面板类(或IPanel接口)和CarPanel、HotelPanel、TrainPanel等子类的类型模式呢。。。使用ViewModel对象,视图代码变得更加简单:

var newPanel = PanelFactory.GetPanel(data);  //Returns a CarPanel, HotelPanel, TrainPanel...
panelTypeList.Add(newPanel);
panelCount++;

您可以随时查看规范模式。对于布尔逻辑非常方便:

public interface ISpecification<T>
{
    public bool IsSatisfiedBy(T candidate);
}
公共接口规范
{
公共学校(T候选人)满意;
}

如果不知道所涉及的类型,例如酒店/汽车/火车属性的类型,以及类型类型,则很难对其进行重构。这有帮助吗?公共枚举类型{Hotel=0,Car=1,Train=2}@James:有一点,但是我们可以了解更多关于模型表示的内容。例如,model.Car和model.Hotel都是真的吗?类型基本上控制要渲染的视图。。因此,它们可能都是真实的,并同时显示,因为它们是局部视图,或者只是部分视图,或者根本没有视图。希望这能有所帮助,谢谢大家的贡献。@James:在这种情况下,检查的顺序非常重要,
panelCount
检查可能是真的,然后是假的……如果成功,你不应该返回1吗?
if(panelCount < NumberOfPanelsToShow)
switch (Model.ModelType)
{
    case ModelType.Train :
        ...
        break;

    case ModelType.Plane :
...
}
if (panelCount < NumberOfPanelsToShow)
{
    panelCount += AddModel(model);
}

private int AddModel(Plane model)
{ // do plane stuff here and on success return 1 else 0; }

private int AddModel(Train model)
{ // do train stuff here and on success return 1 else 0; }

private int AddModel(Car model)
{ // do car stuff here and on success return 1 else 0; }
var newPanel = PanelFactory.GetPanel(data);  //Returns a CarPanel, HotelPanel, TrainPanel...
panelTypeList.Add(newPanel);
panelCount++;
public interface ISpecification<T>
{
    public bool IsSatisfiedBy(T candidate);
}