Parameter in Methode verwenden

  • C#

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von TheVBTutorialsVB.

    Parameter in Methode verwenden

    Hallo Forum,

    mir ist letztens eine Frage eingefallen, über die ich noch nie nachgedacht hab. Ist es üblich einen Parameter, der kein Referenzparameter ist, direkt in der Methode zu verwenden? Also ist es so

    C#-Quellcode

    1. static byte[] Reverse(byte[] array)
    2. {
    3. byte temp;
    4. byte[] tempArray = array;
    5. for (var i = 0; i < tempArray.Length / 2; i++)
    6. {
    7. temp = tempArray[i];
    8. tempArray[i] = tempArray[tempArray.Length - 1 - i];
    9. tempArray[tempArray.Length - 1 - i] = temp;
    10. }
    11. return tempArray;
    12. }


    oder so

    C#-Quellcode

    1. static byte[] Reverse(byte[] array)
    2. {
    3. byte temp;
    4. for (var i = 0; i < array.Length / 2; i++)
    5. {
    6. temp = array[i];
    7. array[i] = array[array.Length - 1 - i];
    8. array[array.Length - 1 - i] = temp;
    9. }
    10. Console.WriteLine();
    11. return array;
    12. }


    besser? In der Schule wurde uns gesagt es sei unschön ist den Parameter direkt zu verwenden, allerdings bin ich mir da nicht sicher (wir programmieren in Delphi und sollen Methoden kleinschreiben etc., also sehe ich die Ansichten meines Lehrers ohnehin kritisch).

    LG

    TheVBTutorialsVB schrieb:

    also sehe ich die Ansichten meines Lehrers ohnehin kritisch
    Jo, ich bin auch ein sehr kritischer Lehrer-Seher.

    Wenner keine weiteren Argumente als "Schönheit" hat, dann scheint mir das nicht so wichtig.
    Meine Wenigkeit achtet sehr darauf, kein üflüssiges Zeug zu schreiben.
    Aber deine Methode ist nicht nur bisserl zu länger als nötig, sondern problematisch ist v.a. der Rückgabewertes. Das macht den User denken, er bekomme was anderes zurück, als er bereits hat, aber das ist garnicht der Fall.
    Sondern sein Original-Array wird revertiert - und das mag ihn überraschen (und Überraschungen sind immer schlecht inne Programmierung).
    Also ich würde so machen:

    C#-Quellcode

    1. static void Reverse(byte[] bytes) {
    2. for (int i = 0, i2 = bytes.Length - 1; i < i2; i++, i2--) {
    3. var temp = bytes[i];
    4. bytes[i] = bytes[i2];
    5. bytes[i2] = temp;
    6. }
    7. }
    Das ist kurz und kann den Aufrufer nicht überraschen.
    Auch wird die temp-Variable genau da deklariert, wo sie benötigt wird. Ist kürzer, und besser gekapselt.
    Auch habe ich nicht in jedem Schleifen-Durchgang eine vergleichsweise teure Division.
    Du siehst: "Schönheit" ist kein Argument, sondern ist beim coden ein Nebenprodukt, was sich imo von selbst einstellt - wenn Code viele benennbare Vorzüge hat.

    ...wenn ich das überhaupt machen würde, weil es gibt ja bereits eine Array.Reverse-Methode.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Das macht den User denken, er bekomme was anderes zurück, als er bereits hat, aber das ist garnicht der Fall.


    Ich verstehe nicht wirklich was du meinst. Wenn du eine Methode aufrufst die Reverse heißt, die ein Byte-Array annimmt und zurückgibt, was erwartest du was die Methode macht? Bei einem größerem Projekt würde ich im Zweifelsfall sowieso alles mit XML-Comments übersehen.

    ErfinderDesRades schrieb:

    ...wenn ich das überhaupt machen würde, weil es gibt ja bereits eine Array.Reverse-Methode.


    Es hat auch keinen anderen Sinn als eine Aufgabe zu lösen, die ich in einem C#-Buch gefunden hab, welches ich gerade lese. Eigentlich ist die Aufgabe Schwachsinn, weil sie so trivial ist, allerdings dachte ich, dass ich das Buch gründlich durcharbeite (hab auch einiges triviales gelernt, das ich noch nicht kannte). So wie ich jetzt gerade gelernt habe, dass ich mehr als nur i++ in die for-loop schreiben kann, danke dafür :3

    TheVBTutorialsVB schrieb:

    Ich verstehe nicht wirklich was du meinst. Wenn du eine Methode aufrufst die Reverse heißt, die ein Byte-Array annimmt und zurückgibt, was erwartest du was die Methode macht?
    Wenn mir eine Methode etwas zurückgibt erwarte ich, dasses etwas anderes ist, als ich schon habe.
    Eine Methode, die mir dasselbe Objekt zurückgibt, was ich ihr gebe, dürfte iwann Verwirrung stiften.
    probier das:

    C#-Quellcode

    1. static public void TestMethod() {
    2. var arr = Enumerable.Range(0, 7).Select(i => (Byte)i).ToArray();
    3. var aufsteigend = arr[0] < arr[1];
    4. MessageBox.Show("arr aufsteigend sortiert: " + aufsteigend);
    5. var arr2 = Reverse(arr);
    6. aufsteigend = arr[0] < arr[1];
    7. MessageBox.Show("arr aufsteigend sortiert: " + aufsteigend);
    8. var arr3 = Reverse(arr2);
    9. aufsteigend = arr[0] < arr[1];
    10. MessageBox.Show("arr aufsteigend sortiert: " + aufsteigend);
    11. if (aufsteigend) {
    12. MessageBox.Show("Nanu - arr wieder aufsteigend - ich habs doch nur einmal reverted!\n Hat das Reverten von arr2 auch arr revertiert???");
    13. }
    14. }
    Diese überraschung passiert nicht, wenn Reverse einfach nix zurückgibt ( void )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Diese überraschung passiert nicht, wenn Revert einfach nix zurückgibt ( void )


    Aber wenn ich das übergebene Array nicht als Referenzparameter übergebe und keinen Wert zurückgebe, dann ändere ich doch überhaupt nichts oder? Dann editiere ich die Kopie (weil der Parameter = value-Type) und nach der Methode existiert die Kopie nicht mehr.

    Die Lösung scheint theoretisch zu funktionieren auch wenn sie mir nicht wirklich gefällt:

    C#-Quellcode

    1. static byte[] Reverse(byte[] array)
    2. {
    3. byte temp;
    4. byte[] tempArray = new byte[array.Length];
    5. for (var i = 0; i < array.Length; i++)
    6. {
    7. tempArray[i] = array[i];
    8. }
    9. for (var i = 0; i < tempArray.Length / 2; i++)
    10. {
    11. temp = tempArray[i];
    12. tempArray[i] = tempArray[tempArray.Length - 1 - i];
    13. tempArray[tempArray.Length - 1 - i] = temp;
    14. }
    15. Console.WriteLine();
    16. return tempArray;
    17. }


    Edit: Ups, hab vergessen, dass Arrays Referenztypen sind...

    ja, genau.
    Entweder - wie dein neuerlicher code - du gibst ein anderes Array zurück.
    Oder (meine Präferenz) du gibst gar nichts zurück - dann ist ja auch eindeutig, welches array reverted wurde.

    Aber von meinen anderen Anmerkungen (teure Division, Variablen deklarieren, wo gebraucht (Scope begrenzen)) scheint auch nix bei dir angekommen zu sein :(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Okay ich verstehe.

    ErfinderDesRades schrieb:

    Aber von meinen anderen Anmerkungen (teure Division, Variablen deklarieren, wo gebraucht (Scope begrenzen)) scheint auch nix bei dir angekommen zu sein


    Doch, ich habs nur noch nicht abgeändert weil

    1) Das ja nicht das eigentliche Problem war, ich wollte zunächst, dass der Code funktioniert.
    2) Ich das Projekt jetzt sowieso gelöscht habe, da ich ja nur die Aufgabe bearbeitet habe und die Funktion wie bereits erwähnt unsinnig ist.
    3) Du hast die Lösung bereits gepostet, was nützt es wenn ich sie reposte. Ich wollte nur meine Alternativlösung posten, die nicht optimiert ist, sondern nur eine andere Möglichkeit ein Array zurückzugeben darstellt. Ich habe den Kern deiner Aussage verstanden und setzte das in Zukunft auch so um.

    TheVBTutorialsVB schrieb:

    So wie ich jetzt gerade gelernt habe, dass ich mehr als nur i++ in die for-loop schreiben kann, danke dafür :3


    Ich denke ich habe außerdem erwähnt, dass ich die Kritik an der Division verstanden habe (und somit auch deine anderen Punkte bzgl Scoping etc).