Forum: PC-Programmierung C#: Manipulierte Eingangsparameter kennzeichnen


von Horst S. (Gast)


Lesenswert?

Bei folgender Problemstellung bete ich immer, dass mein Quellcode so gut 
läuft, dass ich ihn nie mehr anschauen muss (sonst habe ich sowieso 
wieder vergessen, was da passiert):
Als Array vorliegende Daten müssen durch unterschiedliche Funktionen 
klassifiziert werden. Konkret geht es um einen Rundumsensor, dessen 
einzelne Punkte in Linien, Punktwolken und Restpunkte zerlegt werden. Um 
kenntlich zu machen, dass Punkte einer Linie nicht mehr für Punktwolken 
oder Restpunkte zur Verfügung stehen, werden die Werte in der 
entsprechenden Klassifizierung auf null gesetzt.
Irgendwie aber blöde zu lesen. Weder "ref" noch "out" scheinen das 
richtige Schlüsselchen zu sein, um meinem Kollegen (oder mir in einem 
halben Jahr) zu zeigen, dass das Eingabefeld über die Unterroutinen von 
ProcessInput manipuliert wird. Bleibt mir da wirklich nur die 
Kommentierung?

1
        /// <summary>
2
        /// ...
3
        /// </summary>
4
        /// <remarks>"samples" parameter will be destroyed after call</remarks> 
5
        public List<IPart> ProcessInput(ScanPoint[] samples)
6
        {
7
            List<IPart> rval = new List<IPart>(); 
8
            rval.AddRange ( GetLines(samples));
9
            rval.AddRange ( GetPointClouds(samples));
10
            rval.AddRange ( GetPoints(samples));
11
            return rval;
12
        }
13
14
15
16
        /// <summary>
17
        /// ...
18
        /// </summary>
19
        /// <param name="samples"></param>
20
        /// <returns></returns>
21
        /// <remarks>used points will be wiped out from samples</remarks> 
22
        List<IPart> GetLines(ScanPoint[] samples)
23
        {
24
            List<IPart> rval = new List<IPart>();
25
            //Identify lines ...
26
27
            //dummy: wipe out used input points
28
            for (int i = 0; i < 42; i++)
29
            {
30
                samples[i] = null;
31
            }
32
            return rval;
33
        
34
        }
35
36
        /// <remarks>used points will be wiped out from samples</remarks> 
37
        List<IPart> GetPointClouds(ScanPoint[] samples)
38
        {
39
            List<IPart> rval = new List<IPart>();
40
            //Identify PointClouds ...
41
42
            //dummy: wipe out used input points
43
            for (int i = 42; i <= 84; i++)
44
            {
45
                samples[i] = null;
46
            }
47
            return rval;
48
49
        }
50
51
        List<IPart> GetPoints(ScanPoint[] samples)
52
        {
53
            foreach (ScanPoint ptIn in samples)
54
            {
55
                if (ptIn != null)
56
                {    // Ahh, its a point, so add it to rval;
57
                }
58
            }
59
60
61
        }

Merke: Es geht nicht darum, das Eingangsfeld vor der Zerstörung (durch 
kopieren) zu retten, sondern einen Reminder zu setzen, dass das 
Eingangsfeld zerstört wird.

Oder baut Ihr so etwas erst gar nicht?

Oder bin ich mittlerweile zu empfindlich?

von Peter II (Gast)


Lesenswert?

1
   List<IPart> GetPointClouds(ScanPoint[] samples)
2
        {
3
            List<IPart> rval = new List<IPart>();
4
            //Identify PointClouds ...
5
6
            //dummy: wipe out used input points
7
            for (int i = 42; i <= 84; i++)
8
            {
9
                samples[i] = null;
10
            }
11
            return rval;
12
13
        }

das macht doch irgendwie keinen sinn. eine neue Liste zu erzeugen wo 
alle werte null sind.

Warum nicht einfach jeden Punkt aus der Liste löschen, wenn er 
verarbeitet ist. Dann musst du auch nicht auf null prüfen?

1
List<IPart> x = new List<IPart>();
2
3
// Punkte hinzufügen
4
x.Add(...);
5
6
// Funktion 1
7
x.Del( )
8
9
// Funktion 2
10
x.Del( )

dafür braucht man auch kein ref oder out, weil komplex Objekte immer als 
Referenz übergeben werden

von Horst S. (Gast)


Lesenswert?

Unter Berücksichtigung, dass...
- samples an alle Unterfunktionen als Eingangsparameter weitergegeben 
wird
- IPart ein Interface für die zurückgegebenen Typen Linie Punktwolke und 
Restpunkte ist.
- das zurückgegebene List<IPart> der Unterfunktionen also eine Sammlung 
der jeweils klassifizierten Objekte zurückgibt
- In jeder Unterfunktion die von den erstellten Objekten verwendeten 
ScanPoints auf null gesetzt werden müssen (Ein ScanPoint kann nur 
ENTWEDER Bestandteil einer Linie ODER einer Punktwolke ODER ein 
verbleibender Einzelpunkt sein), damit sie in der folgenden Funktion 
nicht mehr verwendet werden.

...muss ich jetzt erst einmal fragen, was Du damit meinst (sorry).

von Horst S. (Gast)


Lesenswert?

Vielleicht muss ich mal meine Frage umformulieren:

Welche Schweincheleien lasst Ihr in Euren Schnittstellen selber zu, 
damit Euer Code einerseits performt und andererseits Euch morgen noch 
schmeckt?

Ich sag mal, mit oben gezeigten zurücksetzen der ScanPoints auf null 
verstoße ich zumindest gegen das Paradigma, dass ich nicht weiß, wer 
mich aufruft und ob der Aufrufer den Eingangsparameter noch für etwas 
anderes braucht.

Kopieren ist allerdings auch blöd, wenn die Eingangswerte nirgendwo 
anders verwendet werden.

Hmm, vielleicht könnte ich eine Überladung einbauen:
1
public List<IPart> ProcessInput(ScanPoint[] samples, bool noDestroy)
2
{
3
    if (noDestroy)
4
        return ProcessInput((LineFinderInputPoint[]) samples.Clone());
5
    else
6
        return ProcessInput(samples);
7
8
}

manchmal findet man ja schon den Sinn der Sache, wenn man in der 
Schnittstelle sieht, dass es Alternativen gibt.

von Tom (Gast)


Lesenswert?

Horst S. schrieb:
> Oder bin ich mittlerweile zu empfindlich?

Nein. Eine Funktion, die ganz unschuldig GetPoints heißt und dann ihre 
Eingabe zerstört, geht gar nicht. ExtractPointsAndWipeUsedSamples() oder 
so wäre OK.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.