Zu viele Schleifen in Drawing App

2570
RoflcoptrException

Ich habe eine Methode, die viele Schleifen hat:

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

Gibt es eine einfache Möglichkeit, dies zu verbessern? Und damit es nicht nur für 6 Schritte, sondern auch für n Schritte funktioniert?

Antworten
31
tl; dr. Sie werden wahrscheinlich eine bessere Antwort erhalten, wenn Sie viel von der Boilerplate entfernen oder sich auf den Teil konzentrieren, an dem Sie wirklich interessiert sind. Ich denke, Pseudo-Code würde hier viel helfen. Wade Tandy vor 9 Jahren 17
Wenn Sie die Verwendung von Kopieren und Einfügen in Betracht ziehen, sollten Sie dies nicht tun. Machen Sie eine Methode und rufen Sie sie zweimal an. adamk vor 9 Jahren 12
Teilen Sie Ihre Methode in viele kleinere auf. vor 9 Jahren 3
Selbst wenn Ihr Code abstrahiert ist, ist das Ändern dieser Änderung von einer statischen Tiefe in eine Tiefe von n nicht sehr trivial und kein Thema für diese Site. Sie benötigen Formeln anstelle von Konstanten und Rekursion oder eine andere vollständig unterschiedliche Schleifenstruktur, um durch den Baum zu gehen (abhängig davon, wie tief die Rekursion gehen soll, wird dies aufgrund des begrenzten Speicherplatzes problematisch, obwohl Optimierungen auf x64-Computern dazu beitragen können). . Unabhängig davon ist die Überprüfung einhellig: Refaktor / Zusammenfassung und Verbesserung der Namensgebung; Die Lösung für Ihr ungelöstes Problem ist jedoch eine andere Site. TheXenocide vor 9 Jahren 0

11 Antworten auf die Frage

61
LRE

Unterteilen Sie das in mehrere Methoden - es ist sehr lang, das heißt, es ist nicht leicht zu lesen.

Eigentlich ist es sogar noch länger;) Ich konnte die gesamte Methode wegen der Zeichenbegrenzung nicht posten;) RoflcoptrException vor 9 Jahren 1
@ Roflcoptr Sie müssen versuchen, meine bisherigen 1200 Zeilen langen Supervisor-Methoden zu schlagen. Definieren Sie es definitiv, es ist ein Albtraum im Entstehen. MetalMikester vor 9 Jahren 2
+1 Definiere es definitiv in kleinere Methoden - und benutze auch Linq !! Aim Kai vor 9 Jahren 1
@Roflcoptr Wenn Sie in der Zukunft viel Code veröffentlichen müssen, versuchen Sie es vielleicht mit [GitHub Gists] (https://gist.github.com/). * (Obwohl es wahrscheinlich ein guter Hinweis ist, dass Ihr Beispiel zu lang ist, wenn es nicht passt.) * Captain Man vor 4 Jahren 0
58
Carlos Muñoz

Dieser Code ...

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

Könnte besser mit einem Array implementiert werden ...

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

Oder Wörterbuch ...

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

Auf diese Weise könnte man es einfach sagen

Canvas.SetTop(g1, values[depth])
Alternativ würde eine switch-Anweisung helfen und absolut keinen Overhead einführen (tatsächlich ist sie schneller als wiederholte "if / else" -Operationen). Felix Dombek vor 9 Jahren 3
@ Felix: Aber eine switch-Anweisung würde den Code nicht wirklich kürzer machen. Adam Lear vor 9 Jahren 16
Es scheint einige Vorurteile zu geben, eine Kontrollanweisung genau für das, was sie gemacht wurde, zu verwenden. Ich begrüße die Kürze, aber wenn es sich um eine eigene Methode handelt, wird sie wieder lesbar sein, und wenn die Leistung einen Unterschied macht, würde ich die switch-Anweisung vorziehen Felix Dombek vor 9 Jahren 4
Vergiss nicht Die Frage sagt, es sollte nicht nur für 6, sondern für Wiederholungen gemacht werden. Es gibt keine dynamischen Schalter. Aber ich stimme zu, dass ein Teil des Codes in seiner eigenen Methode sein sollte Carlos Muñoz vor 9 Jahren 2
Ich bin mir nicht sicher, ob das Ersetzen der else ifs damit lesbarer ist und ob der Code besser wäre. Aim Kai vor 9 Jahren 0
Mmmm mal sehen. Wie würden Sie diese mathematische Funktion implementieren: f (x) = 3x. Auf diese Weise: F (int x) {return 3 * x} Oder auf diese Weise: F (int x) {if (x == 1) return 3; wenn (x == 2) Rückgabe 6; wenn (x == 3) 9 zurückgeben; .....} oder vielleicht so: F (int x) {switch (x) {Fall 1: Return 3; Fall 2: Rückgabe 6; Fall 3 Rückkehr 9; .....}} Carlos Muñoz vor 9 Jahren 0
@Carlos - was wir brauchen, ist eine Formel, um eine Zahl für jedes beliebige * n * auszuspucken. Ich kann mir jetzt noch nicht das Richtige vorstellen, aber es hat wahrscheinlich etwas mit log2 zu tun Felix Dombek vor 9 Jahren 1
28
Nobody

Es gibt ein paar offensichtliche Dinge, die noch nicht erwähnt wurden:

Sie haben viele magische Zahlen in Ihrem Code. Versuchen Sie, sie als consts mit sinnvollen Namen zu definieren .

Zum Beispiel

g.Width = 50;

wird

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

Es scheint eine unbedeutende Änderung zu sein, aber es macht einen großen Unterschied für jemanden, der Ihren Code liest. Es gibt einen Hinweis auf, warum der Wert ist 50, nicht nur, dass es ist 50.


Sie sollten aussagekräftigere Namen für Ihre Bezeichner verwenden. Namen wie gund g1mir nicht viel darüber erzählen, was das Objekt ist, sondern mainGridund innerGridweitere Informationen für den Leser enthält.

Das stimmt in der Tat, zu viele Literale im Code erschweren die Pflege und Anpassung, insbesondere wenn Querverbindungen zwischen den Werten bestehen! Felix Dombek vor 9 Jahren 0
Er sollte static readonly anstelle von const verwenden - dann muss er Assemblys, die von seinem Code abhängen, nicht bei jeder Änderung neu kompilieren müssen! Außerdem ist er nicht nur auf Werte beschränkt, sondern kann auch Referenzen als Konstanten verwenden. Zolomon vor 9 Jahren 1
17
LRE

Denken Sie darüber nach, die Entscheidungen zu abstrahieren, die sich darauf beziehen, den oberen Rand der Zeichenfläche (vgl. All diese ifAnweisungen) in eine Reihe von Klassen zu setzen - oder vielleicht eine einzelne Klasse mit verschiedenen geeigneten Parametern im Konstruktor. Ein großer Teil dieses Codes unterscheidet sich nur in den verwendeten Zahlen.

Eine einfache Regel ist "Abstrakt das Konzept, das variiert".

17
Alex ten Brink

Da Sie C # verwenden, können Sie Ihre Initialisierer ein wenig schöner machen:

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

Der letzte Teil Ihres Codes (oder besser die zweite Hälfte) führt mehrere Male sehr ähnliche Vorgänge durch: Die Duplizierung von Codes ist ein Zeichen, dass Ihr Code klarer dargestellt werden kann. Zum Beispiel (Beachten Sie, dass Ihr Code fast sicher einen Fehler enthält! Die Anweisung in allen Schleifen ruft s2 und nicht s3 auf):

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

kann in geändert werden

list.CountRecursive(t => t.getInvocations(), t => t.getInvocations().Count, 5);

(...)

public static int CountRecursive<T>(this IEnumerable<T> x, Func<T, IEnumerable<T>> f, Func<T, int> c, int depth)
{
    int counter = 0;
    foreach (T t in x)
    {
        if (depth > 1)
        {
            counter += f(t).CountRecursive(f, c, depth - 1);
        }
        else
        {
            counter += c(t);
        }
    }
    return counter;
}

Dies macht es auch viel einfacher, es für verschiedene Rekursionsebenen zu tun.

8
percent20

Ich kann die Verwendung von switch-Anweisungen und Leerzeichen zusammen mit dem Vorschlag von LRE empfehlen, dies in mehrere Methoden aufzuteilen. Es sieht auch so aus, als hätten Sie ziemlich viel wiederholten Code, vielleicht versuchen Sie, das mit seinen eigenen Methoden herauszubekommen.

In diesem Fall ist der Schalter möglicherweise nicht die beste Option. Dadurch würde der Code anstelle von if / else verwendet, der Code ist jedoch fast gleich lang Carlos Muñoz vor 9 Jahren 0
7
munificent

Ich habe es für dich umgestaltet. Ich habe das alles ohne zu testen gemacht, also gibt es wahrscheinlich eine Reihe von Fehlern und Fehler, die einzeln auftreten. Ich habe auch einige Annahmen über den Code gemacht, den Sie nicht hinzugefügt haben. Jetzt, da der Code viel kleiner ist, sollte es einfacher sein, diese Fehler zu finden.

Einige wichtige Punkte:

  1. Rekursion ist ein grundlegendes Konzept bei der Programmierung. Wenn Sie ein professioneller Programmierer sind, müssen Sie sich absolut damit auskennen, sonst werden Sie niemals in der Lage sein, verschachtelte Strukturen effektiv zu behandeln.

  2. Wenn Sie kopieren und einfügen, machen Sie es falsch. Jedes Mal, wenn Sie Strg + C drücken, stirbt ein Kätzchen. Nein nein Nein.

  3. Wenn Sie Variablen mit den Namen haben something1, something2, something3etc. bist du es falsch zu machen . Zumindest sollten diese ein Array sein.

  4. Sie hatten es depthals double, verglichen es jedoch mit anderen Werten als Null. Das ist schlecht.

Bitte schön:

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);
}
6
Sean Lynch

Dies sollte die Schleife vereinfachen, vorausgesetzt, Sie können den Positionscode wie in einigen anderen Antworten erwähnt verallgemeinern

        //Get the initial set of sourcefiles
        var sourceFiles = from file in list
              from invocation in file.getInvocations()
              group invocation by (SourceFile)null into groupedByInvoker
              select groupedByInvoker;

        for (var currentDepth = 0; currentDepth <= depth; currentDepth++)
        {
            foreach (var currentGroup in sourceFiles)
            {
                int sourceFileCount = currentGroup.Count();
                int counter = 0;

                foreach (var invocation in currentGroup)
                {
                    /*
                     * Generalized grid code goes here
                     */
                    counter++;
                }
            }

            //Select the current sub source files
         sourceFiles = from invokerGroup in sourceFiles
              from file in invokerGroup
              from invocation in file.getInvocations()
              group invocation by file into groupedByInvoker
              select groupedByInvoker;

        }

Dies ist keine exakte Zuordnung zum obigen Code, da dies die Breite des getInvocations-Baums zuerst und nicht die Tiefe zuerst überschreitet.

Aktualisiert mit Imput aus Update-Raster aus der Quellhierarchie

5
LRE

Erwägen Sie für das n-Step-Bit die Verwendung von Rekursion - aber gehen Sie vorsichtig vor.

3
Ruudjah

Anstelle von Grid gund Ellipse everwenden Sie Grid gridund Ellipse ellipse. Eine Lok mit e.size=sagt weniger als ellipse.Size=.

Du hast absolut recht, aber ich glaube nicht, dass dies hier das eigentliche Problem ist;) RoflcoptrException vor 9 Jahren 0