我有一个循环很多的方法:

private void update(double depth)
        {

            Console.WriteLine("update with level " + depth);

            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
                {


            List<Grid> grids = new List<Grid>();

            Dependencies.Children.Clear();

            Grid g = new Grid();
            //Canvas.SetZIndex(g, 100);
            g.Width = 50;
            g.Height = 50;
            g.Tag = focus;

            Ellipse e = new Ellipse();
            e.Width = 50;
            e.Height = 50;
            e.Fill = Brushes.Red;
            if (depth == 1)
            {
                Canvas.SetTop(g, 163);
            }
            else if (depth == 2)
            {
                Canvas.SetTop(g, 108);
            }
            else if (depth == 3)
            {
                Canvas.SetTop(g, 81);
            }
            else if (depth == 4)
            {
                Canvas.SetTop(g, 65);
            }
            else if (depth == 5)
            {
                Canvas.SetTop(g, 54);
            }
            else if (depth == 6)
            {
                Canvas.SetTop(g, 46);
            }
            Canvas.SetLeft(g, 500);

            g.Children.Add(e);

            Viewbox box = new Viewbox();
            box.Width = e.Width;
            box.Height = e.Height;


            TextBox txt = new TextBox();
            txt.Text = focus.getName();
            box.Child = txt;
            txt.Background = Brushes.Transparent;
            txt.BorderBrush = Brushes.Transparent;

            g.Children.Add(box);



            grids.Add(g);

            List<SourceFile> list = new List<SourceFile>();

            list = focus.getInvocations();

            int counter = 1;
            foreach (SourceFile sf in list)
            {
                Grid g1 = new Grid();
                //Canvas.SetZIndex(g, 101);
                g1.Width = 50;
                g1.Height = 50;
                g1.Tag = sf;

                Ellipse e1 = new Ellipse();
                //Dependencies.Children.Add(e1);
                sf.setGrid(g1);
                e1.Width = 50;
                e1.Height = 50;
                e1.Fill = Brushes.Red;

                g1.Children.Add(e1);

                if (depth == 1)
                {
                    Canvas.SetTop(g1, 488);
                }
                else if (depth == 2)
                {
                    Canvas.SetTop(g1, 324);
                }
                else if (depth == 3)
                {
                    Canvas.SetTop(g1, 244);
                }
                else if (depth == 4)
                {
                    Canvas.SetTop(g1, 195);
                }
                else if (depth == 5)
                {
                    Canvas.SetTop(g1, 163);
                }
                else if (depth == 6)
                {
                    Canvas.SetTop(g1, 139);
                }
                Canvas.SetLeft(g1, counter * (1000 / (list.Count + 1) ));

                Viewbox box1 = new Viewbox();
                box1.Width = g1.Width;
                box1.Height = g1.Height;

                TextBox txt1 = new TextBox();
                txt1.Text = sf.getName();
                txt1.Background = Brushes.Transparent;
                txt1.BorderBrush = Brushes.Transparent;

                box1.Child = txt1;
                g1.Children.Add(box1);

                Line l = new Line();
                //Canvas.SetZIndex(l, 1);
                l.Stroke = Brushes.Green;
                l.StrokeThickness = 10;
                Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                x1.Converter = new MyConverter();
                x1.ConverterParameter = g;
                Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                y1.Converter = new MyConverter();
                y1.ConverterParameter = g;
                Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                x2.Converter = new MyConverter();
                x2.ConverterParameter = g1;
                Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                y2.Converter = new MyConverter();
                y2.ConverterParameter = g1;
                x1.Source = y1.Source = g;
                x2.Source = y2.Source = g1;
                l.SetBinding(Line.X1Property, x1);
                l.SetBinding(Line.Y1Property, y1);
                l.SetBinding(Line.X2Property, x2);
                l.SetBinding(Line.Y2Property, y2);
                Dependencies.Children.Add(l);
                l.Tag = new Call(focus, sf);
                Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                counter++;

                grids.Add(g1);

                SizeChangedEventHandler act = (Object s, SizeChangedEventArgs args) =>
                {
                    BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                };

                g.SizeChanged += act;
                g1.SizeChanged += act;
            }


            int counter2 = 1;
            if (depth >= 2)
            {

                int invocCount = 0;

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        invocCount = invocCount + s.getInvocations().Count;
                    }
                }

                Console.WriteLine(invocCount);

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {

                        Console.WriteLine("`Found invocation of " + s.getName() + ": " + source.getName());

                        Grid g1 = new Grid();
                        g1.Width = 50;
                        g1.Height = 50;

                        Ellipse e1 = new Ellipse();
                       // Canvas.SetZIndex(g1, 102);
                        grids.Add(g1);
                        e1.Width = 50;
                        e1.Height = 50;
                        e1.Fill = Brushes.Red;
                        source.setGrid(g1);
                        g1.Tag = source;

                        g1.Children.Add(e1);

                        if (depth == 2)
                        {
                            Canvas.SetTop(g1, 540);
                        }
                        else if (depth == 3)
                        {
                            Canvas.SetTop(g1, 406);
                        }
                        else if (depth == 4)
                        {
                            Canvas.SetTop(g1, 325);
                        }
                        else if (depth == 5)
                        {
                            Canvas.SetTop(g1, 271);
                        }
                        else if (depth == 6)
                        {
                            Canvas.SetTop(g1, 232);
                        }

                        Canvas.SetLeft(g1, counter2 * (1000 / (invocCount + 1)));

                        Viewbox box1 = new Viewbox();
                        box1.Width = g1.Width;
                        box1.Height = g1.Height;

                        TextBox txt1 = new TextBox();
                        txt1.Text = source.getName();
                        txt1.Background = Brushes.Transparent;
                        txt1.BorderBrush = Brushes.Transparent;

                        box1.Child = txt1;
                        g1.Children.Add(box1);

                        Line l = new Line();
                        //Canvas.SetZIndex(l, 2);
                        l.Stroke = Brushes.Green;
                        l.StrokeThickness = 10;
                        Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                        x1.Converter = new MyConverter();
                        x1.ConverterParameter = s.getGrid();
                        Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                        y1.Converter = new MyConverter();
                        y1.ConverterParameter = s.getGrid();
                        Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                        x2.Converter = new MyConverter();
                        x2.ConverterParameter = g1;
                        Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                        y2.Converter = new MyConverter();
                        y2.ConverterParameter = g1;
                        x1.Source = y1.Source = findGrid(grids, s, source);
                        x2.Source = y2.Source = g1;
                        l.SetBinding(Line.X1Property, x1);
                        l.SetBinding(Line.Y1Property, y1);
                        l.SetBinding(Line.X2Property, x2);
                        l.SetBinding(Line.Y2Property, y2);
                        Dependencies.Children.Add(l);
                        l.Tag = new Call(s, source);
                        Contacts.AddPreviewContactDownHandler(l, OnLineDown);

                        counter2++;

                        SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                        {
                            BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                        };

                        source.getGrid().SizeChanged += act;
                        g1.SizeChanged += act;
                    }
                }
            }


            int counter3 = 1;
            if (depth >= 3)
            {

                int invocCount = 0;

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        foreach (SourceFile s1 in source.getInvocations())
                        {
                            invocCount = invocCount + source.getInvocations().Count;
                        }
                    }
                }

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        foreach (SourceFile s1 in source.getInvocations())
                        {
                            Grid g1 = new Grid();
                            grids.Add(g1);
                            g1.Width = 50;
                            g1.Height = 50;
                            g1.Tag = s1;
                            Ellipse e1 = new Ellipse();

                            e1.Width = 50;
                            e1.Height = 50;
                            e1.Fill = Brushes.Red;
                            s1.setGrid(g1);
                            g1.Children.Add(e1);

                            if (depth == 3)
                            {
                                Canvas.SetTop(g1, 569);
                            }
                            else if (depth == 4)
                            {
                                Canvas.SetTop(g1, 455);
                            }
                            else if (depth == 5)
                            {
                                Canvas.SetTop(g1, 379);
                            }
                            else if (depth == 6)
                            {
                                Canvas.SetTop(g1, 325);
                            }
                            Canvas.SetLeft(g1, counter3 * (1000 / (invocCount + 1)));

                            Viewbox box1 = new Viewbox();
                            box1.Width = g1.Width;
                            box1.Height = g1.Height;

                            TextBox txt1 = new TextBox();
                            txt1.Background = Brushes.Transparent;
                            txt1.BorderBrush = Brushes.Transparent;
                            txt1.Text = s1.getName();
                            box1.Child = txt1;
                            g1.Children.Add(box1);

                            Line l = new Line();
                            //Canvas.SetZIndex(l, 2);
                            l.Stroke = Brushes.Green;
                            l.StrokeThickness = 10;
                            Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                            x1.Converter = new MyConverter();
                            x1.ConverterParameter = source.getGrid();
                            Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                            y1.Converter = new MyConverter();
                            y1.ConverterParameter = source.getGrid();
                            Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                            x2.Converter = new MyConverter();
                            x2.ConverterParameter = g1;
                            Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                            y2.Converter = new MyConverter();
                            y2.ConverterParameter = g1;
                            x1.Source = y1.Source = findGrid(grids, source, s1);
                            x2.Source = y2.Source = g1;
                            l.SetBinding(Line.X1Property, x1);
                            l.SetBinding(Line.Y1Property, y1);
                            l.SetBinding(Line.X2Property, x2);
                            l.SetBinding(Line.Y2Property, y2);
                            Dependencies.Children.Add(l);
                            l.Tag = new Call(source, s1);
                            Contacts.AddPreviewContactDownHandler(l, OnLineDown);

                            counter3++;

                            SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                            {
                                BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                            };

                            s1.getGrid().SizeChanged += act;
                            g1.SizeChanged += act;
                        }
                    }
                }
            }


         int counter4 = 1;
         if (depth >= 4)
         {

             int invoCount = 0;
             foreach (SourceFile s in list)
             {
                 foreach (SourceFile source in s.getInvocations())
                 {
                     foreach (SourceFile s1 in source.getInvocations())
                     {
                         foreach (SourceFile s2 in s1.getInvocations())
                         {
                             invoCount = invoCount + s1.getInvocations().Count;
                         }
                     }
                 }
             }

             foreach (SourceFile s in list)
             {
                 foreach (SourceFile source in s.getInvocations())
                 {
                     foreach (SourceFile s1 in source.getInvocations())
                     {
                         foreach (SourceFile s2 in s1.getInvocations())
                         {

                             Grid g1 = new Grid();
                             grids.Add(g1);
                             g1.Width = 50;
                             g1.Height = 50;
                             g1.Tag = s2;
                             Ellipse e1 = new Ellipse();

                             e1.Width = 50;
                             e1.Height = 50;
                             e1.Fill = Brushes.Red;
                             s2.setGrid(g1);

                             g1.Children.Add(e1);

                             if (depth == 4)
                             {
                                 Canvas.SetTop(g1, 585);
                             }
                             else if (depth == 5)
                             {
                                 Canvas.SetTop(g1, 488);
                             }
                             else if (depth == 6)
                             {
                                 Canvas.SetTop(g1, 418);
                             }
                             Canvas.SetLeft(g1, counter4 * (1000 / (invoCount + 1)));

                             Viewbox box1 = new Viewbox();
                             box1.Width = g1.Width;
                             box1.Height = g1.Height;

                             TextBox txt1 = new TextBox();
                             txt1.Background = Brushes.Transparent;
                             txt1.BorderBrush = Brushes.Transparent;
                             txt1.Text = s2.getName();
                             box1.Child = txt1;
                             g1.Children.Add(box1);

                             Line l = new Line();
                             //Canvas.SetZIndex(l, 2);
                             l.Stroke = Brushes.Green;
                             l.StrokeThickness = 10;
                             Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                             x1.Converter = new MyConverter();
                             x1.ConverterParameter = s1.getGrid();
                             Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                             y1.Converter = new MyConverter();
                             y1.ConverterParameter = s1.getGrid();
                             Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                             x2.Converter = new MyConverter();
                             x2.ConverterParameter = g1;
                             Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                             y2.Converter = new MyConverter();
                             y2.ConverterParameter = g1;
                             x1.Source = y1.Source = findGrid(grids, s1, s2);
                             x2.Source = y2.Source = g1;
                             l.SetBinding(Line.X1Property, x1);
                             l.SetBinding(Line.Y1Property, y1);
                             l.SetBinding(Line.X2Property, x2);
                             l.SetBinding(Line.Y2Property, y2);
                             Dependencies.Children.Add(l);
                             l.Tag = new Call(s1, s2);
                             Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                             counter4++;

                             SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                             {
                                 BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                             };

                             s2.getGrid().SizeChanged += act;
                             g1.SizeChanged += act;
                         }
                     }
                 }
             }
         }



      int counter5 = 1;
      if (depth >= 5)
      {

          int invoCount = 0;

          foreach (SourceFile s in list)
          {
              foreach (SourceFile source in s.getInvocations())
              {
                  foreach (SourceFile s1 in source.getInvocations())
                  {
                      foreach (SourceFile s2 in s1.getInvocations())
                      {
                          foreach (SourceFile s3 in s2.getInvocations())
                          {
                              invoCount = invoCount + s2.getInvocations().Count;
                          }
                      }
                  }
              }
          }

          foreach (SourceFile s in list)
          {
              foreach (SourceFile source in s.getInvocations())
              {
                  foreach (SourceFile s1 in source.getInvocations())
                  {
                      foreach (SourceFile s2 in s1.getInvocations())
                      {
                          foreach (SourceFile s3 in s2.getInvocations())
                          {
                              Grid g1 = new Grid();
                              g1.Width = 50;
                              g1.Height = 50;
                              grids.Add(g1);
                              g1.Tag = s3;
                              Ellipse e1 = new Ellipse();
                              //Dependencies.Children.Add(e1);
                              e1.Width = 50;
                              e1.Height = 50;
                              e1.Fill = Brushes.Red;
                              s3.setGrid(g1);

                              g1.Children.Add(e1);

                              if (depth == 5)
                              {
                                  Canvas.SetTop(g1, 596);
                              }
                              else if (depth == 6)
                              {
                                  Canvas.SetTop(g1, 511);
                              }
                              Canvas.SetLeft(g1, counter5 * (1000 / (invoCount + 1)));

                              Viewbox box1 = new Viewbox();
                              box1.Width = g1.Width;
                              box1.Height = g1.Height;

                              TextBox txt1 = new TextBox();
                              txt1.Background = Brushes.Transparent;
                              txt1.BorderBrush = Brushes.Transparent;
                              txt1.Text = s3.getName();
                              box1.Child = txt1;
                              g1.Children.Add(box1);

                              Line l = new Line();
                              //Canvas.SetZIndex(l, 2);
                              l.Stroke = Brushes.Green;
                              l.StrokeThickness = 10;
                              Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                              x1.Converter = new MyConverter();
                              x1.ConverterParameter = s2.getGrid();
                              Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                              y1.Converter = new MyConverter();
                              y1.ConverterParameter = s2.getGrid();
                              Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                              x2.Converter = new MyConverter();
                              x2.ConverterParameter = g1;
                              Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                              y2.Converter = new MyConverter();
                              y2.ConverterParameter = g1;
                              x1.Source = y1.Source = findGrid(grids, s2, s3);
                              x2.Source = y2.Source = g1;
                              l.SetBinding(Line.X1Property, x1);
                              l.SetBinding(Line.Y1Property, y1);
                              l.SetBinding(Line.X2Property, x2);
                              l.SetBinding(Line.Y2Property, y2);
                              l.Tag = new Call(s2, s3);
                              Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                              Dependencies.Children.Add(l);

                              counter5++;

                              SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                              {
                                  BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                              };

                              s3.getGrid().SizeChanged += act;
                              g1.SizeChanged += act;
                          }
                      }
                  }
              }
          }
      }



            foreach (Grid grid in grids)
            {
                Dependencies.Children.Add(grid);
                Contacts.AddPreviewContactDownHandler(grid, DownOnSourceFile);
            }
                }
  ));
        }


有没有简单的方法可以改善这种情况?使其不仅可以工作6步,还可以工作n步?

评论

tl;博士如果删除很多样板或专注于您真正感兴趣的部分,您可能会得到更好的响应。我认为伪代码在这里会很有帮助。

每当您想到使用复制和粘贴时,都不要这样做。制作一个方法并调用两次。

将您的方法分解为许多较小的方法。

即使将您的代码抽象化,将其从静态深度更改为n深度对于这个站点也是非常重要的。您将需要公式而不是常量和递归,否则将需要完全不同的循环结构来遍历树(取决于您希望递归的深度,由于堆栈空间有限,尽管在x64机器上进行优化可能会对此有所帮助,但这会成为问题) 。无论如何,评审是一致的:重构/抽象并改善命名;但是,针对您未解决的问题的解决方案是针对其他站点。

#1 楼

将其分解为几种方法-它很长,这意味着不容易阅读。

评论


\ $ \ begingroup \ $
实际上,甚至更长的时间;)由于字符限制,我无法发布整个方法;)
\ $ \ endgroup \ $
– RoflcoptrException
2011年1月20日,0:28

\ $ \ begingroup \ $
@Roflcoptr您必须尝试击败我的前主管1200行长的方法。绝对将其分解,这是一场噩梦。
\ $ \ endgroup \ $
–金属迈克斯特
2011年1月21日,1:10

\ $ \ begingroup \ $
+1肯定会分解为较小的方法-并同时使用一些Linq!
\ $ \ endgroup \ $
–目标启
2011年1月21日在10:24

\ $ \ begingroup \ $
@Roflcoptr以后,如果您需要发布很多代码,请尝试GitHub Gists。 (尽管,这很可能很好地表明您的示例如果不适合,可能会太长。)
\ $ \ endgroup \ $
–曼上尉
2015年5月5日在1:31



#2 楼

此代码...

if (depth == 1)
{
    Canvas.SetTop(g1, 163);
}
else if (depth == 2)
{
    Canvas.SetTop(g1, 108);
}
else if (depth == 3)
{
    Canvas.SetTop(g1, 81);
}
else if (depth == 4)
{
    Canvas.SetTop(g1, 65);
}
else if (depth == 5)
{
    Canvas.SetTop(g1, 54);
}
else if (depth == 6)
{
    Canvas.SetTop(g1, 46);
}


使用数组可以更好地实现...

int[] values = new [] { 0, 163, 108, 81, 65, 54, 46  }


或字典...

var values = new Dictionary<int,int>() { { 1, 163 }, { 2, 108 }, { 3, 81 }, { 4, 65 }, { 5, 54 }, { 6, 46} };


这样您可以简单地说

Canvas.SetTop(g1, values[depth])


评论


\ $ \ begingroup \ $
或者,switch语句将帮助并完全避免开销(实际上,它比重复if / else操作要快)
\ $ \ endgroup \ $
– Felix Dombek
2011年1月20日,0:42

\ $ \ begingroup \ $
@Felix:但是switch语句并不会真正使代码更短。
\ $ \ endgroup \ $
–亚当·李尔♦
2011年1月20日,下午2:18

\ $ \ begingroup \ $
似乎有些偏向完全按照控制语句的要求使用控制语句。我很简洁,但是如果使用它自己的方法,它将再次可读,并且如果性能有所不同,我强烈希望使用switch语句
\ $ \ endgroup \ $
– Felix Dombek
2011年1月20日在22:03

\ $ \ begingroup \ $
不要忘记这个问题,它不仅应该进行6次,还应该进行n次迭代。没有动态n案例开关这样的东西。但是我确实同意代码的一部分应该在它自己的方法中
\ $ \ endgroup \ $
–卡洛斯·穆尼兹(CarlosMuñoz)
2011年1月20日23:59



\ $ \ begingroup \ $
@卡洛斯(Carlos)对-我们需要一个公式,为任何n吐出一个数字。我暂时还没想到正确的方法,但是它可能对log2有所帮助
\ $ \ endgroup \ $
– Felix Dombek
2011年1月21日15:36



#3 楼

还没有提到一些立即显而易见的事情:

您的代码中有很多魔术数字。尝试将它们定义为具有有意义名称的const。例如,

g.Width = 50;

成为

private const int DefaultGridWidth = 50;
...
g.Width = DefaultGridWidth;


似乎是微不足道的更改,但对于正在阅读您的代码的人来说却有很大的不同。它表明为什么值是50,而不仅仅是50。


您应该为标识符使用更有意义的名称。诸如gg1之类的名称并不能告诉我很多关于对象是什么的信息,但是mainGridinnerGrid包含了更多的读者信息。

评论


\ $ \ begingroup \ $
的确如此,代码中过多的文字会使维护和适应变得更加困难,尤其是在值之间存在交叉依赖的情况下!
\ $ \ endgroup \ $
– Felix Dombek
2011年1月20日22:05

\ $ \ begingroup \ $
他应该使用静态只读而不是const-这样,他就不必在每次更改时都重新编译依赖于其代码的程序集!而且,他不仅限于值,还可以将引用用作常量。
\ $ \ endgroup \ $
–所罗门
2011年3月23日在7:47



#4 楼

考虑一下有关将画布顶部(参见所有if语句)设置为一组类的决策(或可能是构造函数中具有不同合适参数的单个类)的抽象决策。这段代码的许多不同之处仅在于所应用的数字。

一个简单的规则是“抽象变化的概念”。

#5 楼

由于您使用的是C#,因此可以使初始化程序更好一些:多次:代码重复是您的代码可以变得更清晰的标志。例如(请注意,您的代码几乎肯定包含一个错误!所有循环中的语句都调用s2而不是s3): >
Grid g = new Grid()
{
    Width = 50,
    Height = 50,
    Tag = focus,
}
//Canvas.SetZIndex(g, 100);


,这对于不同的递归级别也很容易做到。

#6 楼

我可能会建议使用switch语句和空白,以及LRE将其分解为多种方法的建议。看起来您有很多重复的代码,也许可以尝试将其分解以确保它是自己的方法。

评论


\ $ \ begingroup \ $
在这种情况下,开关可能不是最佳选择。它将使代码成为用例,而不是if / else,但代码几乎同样冗长
\ $ \ endgroup \ $
–卡洛斯·穆尼兹(CarlosMuñoz)
2011年1月19日在22:41

#7 楼

我为您重构了它。我在没有测试的情况下完成了所有这些工作,因此可能会出现许多错误和单一错误。我还对您未包含的代码做了一些假设。现在代码已经小了很多,应该更容易找到这些错误。

几个重要点:


递归是一个基本概念在编程中。如果您是一名专业的程序员,则绝对必须对此感到满意,否则您将永远无法有效地处理嵌套结构。
如果复制粘贴,那就错了。每次您按Ctrl + C组合键时,小猫都会死亡。否否否。
如果您有名为something1something2something3等的变量,那么您做错了。至少,这些应该是一个数组。
您将depth用作double,但正在将其与非零的文字值进行比较。不好。

您在这里:

private void update(int depth)
{
    Console.WriteLine("update with level " + depth);

    Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
    {
        List<Grid> grids = new List<Grid>();

        Dependencies.Children.Clear();

        Grid grid = MakeOuterGrid(grids, focus, e.Width, e.Height, depth);

        List<SourceFile> list = focus.getInvocations();

        for (int i = 1; i <= depth; i++)
        {
            int invocCount = CountInvocations(focus, i + 1);
            int counter = 0;
            MakeRecursiveGrids(grids, null, focus, i, invocCount, i, ref counter);
        }

        foreach (Grid grid in grids)
        {
            Dependencies.Children.Add(grid);
            Contacts.AddPreviewContactDownHandler(grid, DownOnSourceFile);
        }
    }));
}

void AdjustTop(int depth, int table) {
    int[][] depthTable = new int[][] {
        new int[] { 163, 108,  81,  65,  54,  46 },
        new int[] { 488, 324, 244, 195, 163, 139 },
        new int[] {  -1, 540, 406, 325, 271, 232 },
        new int[] {  -1,  -1, 569, 455, 379, 325 },
        new int[] {  -1,  -1,  -1, 585, 488, 418 },
        new int[] {  -1,  -1,  -1,  -1, 596, 511 },
    }

    int[] depths = depthTable[table];
    if ((depth < depths.Length) && (depths[depth - 1] != -1)) {
        Canvas.SetTop(depths[depth - 1]);
    }
}

SizeChangedEventHandler UpdateBindings(Line line) {
    SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
    {
        BindingOperations.GetBindingExpressionBase(line, Line.X1Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.Y1Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.X2Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.Y2Property).UpdateTarget();
    };

    return act;
}

int CountInvocations(SourceFile source, int depth)
{
    int count = 0;

    if (depth > 0)
    {
        foreach (SourceFile inner in source.getInvocations())
        {
            count = count + CountInvocations(inner, depth - 1);
        }
    }
    else
    {
        count = source.Count;
    }

    return count;
}

Grid MakeGrid(List<Grid> grids, SourceFile source)
{
    Grid grid = new Grid();
    grid.Width = 50;
    grid.Height = 50;
    grid.Tag = source;
    source.setGrid(grid);
    grids.Add(grid);

    Ellipse ellipse = new Ellipse();
    ellipse.Width = 50;
    ellipse.Height = 50;
    ellipse.Fill = Brushes.Red;

    grid.Children.Add(ellipse);

    return grids;
}

void MakeRecursiveGrids(List<Grid> grids, SourceFile outer, SourceFile source,
    int maxDepth, int invocCount, int recurseDepth, ref int counter)
{
    if (recurseDepth > 0)
    {
        foreach (SourceFile inner in source)
        {
            MakeRecursiveGrids(grids, source, inner, maxDepth, invocCount,
                recurseDepth - 1, ref counter);
        }
    }
    else
    {
        MakeGrid(grids, outer, inner, depth, maxDepth, invocCount, counter);
        counter++;
    }
}

Grid MakeGrid(List<Grid> grids, SourceFile outer, SourceFile inner,
    int depth, int[] depths, int invocCount, int counter)
{
    Grid grid = MakeGrid(grids, inner);

    MakeViewbox(grid, grid.Width, grid.Height, inner.getName());

    AdjustTop(depth, depths);
    Canvas.SetLeft(grid, counter * (1000 / (invocCount + 1)));

    MakeLine(grids, grid, outer, inner);

    return grid;
}

Grid MakeOuterGrid(List<Grid> grids, SourceFile inner, int width, int height,
    int depth)
{
    Grid grid = MakeGrid(grids, inner);

    MakeViewbox(grid, width, height, inner.getName());

    AdjustTop(depth, 0);
    Canvas.SetLeft(grid, 500);

    return grid;
}

Binding MakeBinding(Object parameter, Grid grid)
{
    Binding binding = new Binding();
    binding.Path = new PropertyPath(parameter);
    binding.Converter = new MyConverter();
    binding.ConverterParameter = grid;
}

void MakeLine(List<Grid> grids, Grid grid, SourceFile outer, SourceFile inner)
{
    Grid g2 = outer.getGrid();

    Line line = new Line();
    line.Stroke = Brushes.Green;
    line.StrokeThickness = 10;

    Binding x1 = MakeBinding(Canvas.LeftProperty, g2);
    Binding y1 = MakeBinding(Canvas.TopProperty, g2);
    Binding x2 = MakeBinding(Canvas.LeftProperty, grid);
    Binding y2 = MakeBinding(Canvas.TopProperty, grid);

    Grid g = findGrid(grids, outer, inner);
    x1.Source = g;
    y1.Source = g;
    x2.Source = grid;
    y2.Source = grid;

    line.SetBinding(Line.X1Property, x1);
    line.SetBinding(Line.Y1Property, y1);
    line.SetBinding(Line.X2Property, x2);
    line.SetBinding(Line.Y2Property, y2);

    Dependencies.Children.Add(line);

    Contacts.AddPreviewContactDownHandler(line, OnLineDown);

    line.Tag = new Call(outer, inner);

    SizeChangedEventHandler act = UpdateBindings(line);
    inner.getGrid().SizeChanged += act;
    g1.SizeChanged += act;
}

void MakeViewBox(Grid grid, int width, int height, string text)
{
    Viewbox box = new Viewbox();
    box.Width = width;
    box.Height = height;

    TextBox textBox = new TextBox();
    textBox.Text = text;

    box.Child = textBox;

    grid.Children.Add(box);
}


#8 楼

假设您可以像在其他几个答案中提到的那样概括定位代码,这应该简化循环。

这首先遍历了getInvocations树的宽度,而不是深度。

从源层次结构的Update grid中使用imput更新

#9 楼

对于n步位,请考虑使用递归-但要谨慎行事。

#10 楼

使用Grid gEllipse e代替Grid gridEllipse ellipse。具有e.size=的位置表示少于ellipse.Size=

评论


\ $ \ begingroup \ $
你绝对是正确的,但是我不认为这是真正的问题;)
\ $ \ endgroup \ $
– RoflcoptrException
11年1月27日在21:47

#11 楼

当然,还有其他方法可以将您的代码分解成自己的方法,但这可能是最简单,最省时的方法,使您可以更轻松地阅读和调试入门。