Ist es eine schlechte Praxis, Methodenparameter wiederzuverwenden?

12

Es gibt Zeiten, in denen ich einen an eine Methode übergebenen Wert innerhalb der Methode selbst ändern muss. Ein Beispiel wäre das Bereinigen einer Zeichenfolge wie der folgenden:

void SanitizeName(string Name)
{
    Name = Name.ToUpper();

    //now do something here with name
}

Dies ist rein harmlos, da das NameArgument nicht als Referenz übergeben wird. Wenn jedoch ein Entwickler in Zukunft aus irgendeinem Grund entscheidet, dass alle Werte per ref übergeben werden, wirkt sich eine Bereinigung des Strings auf den Wert außerhalb der Methode aus, was zu nachteiligen Ergebnissen führen kann.

Anstatt das Argument selbst neu zuzuweisen, erstelle ich daher immer eine lokale Kopie wie folgt:

void SanitizeName(string Name)
{
    var SanitizedName = Name.ToUpper();

    //now do something here with name
}

Dies stellt sicher, dass Änderungen an der Übergabe des Werts niemals die Vorgänge außerhalb der Methode beeinflussen, aber ich frage mich, ob ich diesbezüglich übermäßig paranoid bin.

oscilatingcretin
quelle
1
Ja, es ist eine schlechte Übung. und nein, es ist nicht harmlos. Die Zeile Name = Name.ToUpper();macht es schwieriger, dem Code in Ihrem Kopf zu folgen, wenn sich der Wert Nameändert. Ihr zweites Beispiel ist nicht nur zukunftssicherer, es ist auch einfacher zu überlegen, was es tut.
David Arno
2
Aber was ist mit if (param == NULL) param = default_value;?
Aragaer
Ich denke, es ist nicht so einfach wie Ja / Nein.
MrSmith42
3
Wenn sich "ein Entwickler in Zukunft entscheidet, alle Werte als ref übergeben zu lassen" , hätte ich wahrscheinlich ein Argument mit diesem Entwickler, die Wiederverwendung von Parametern oder nicht ;-) Ehrlich gesagt, wenn man sich entscheidet, einen Wert zu übergeben, by refder nicht übergeben wurde Um aus irgendeinem Grund den lokalen Zugriff in einen nicht lokalen Zugriff umzuwandeln, muss er die Konsequenzen immer sorgfältig prüfen.
Doc Brown
2
Ich arbeite in erster Linie in einem Paradigma , wo wir nie neu zuweisen aller Variablen. Je. Es ist lustig, sich jemanden vorzustellen, der mit der Frage kämpft, ob er eine kleine Minderheit von Variablen neu zuordnen und sich dann keine Sorgen mehr darüber machen soll, ob er mit dem Rest wild wird.
Karl Bielefeldt

Antworten:

10

Ich denke, es hängt von Ihren Kodierungskonventionen in Ihrem Projekt ab.

Ich persönlich habe Eclipse das finalSchlüsselwort automatisch zu jeder Variablen und jedem Parameter hinzufügen lassen . So sehen Sie auf den ersten Blick, ob ein Parameter wiederverwendet wird.

In meinem Job empfehlen wir nicht, Parameter wiederzuverwenden, aber wenn Sie nur z. B. aufrufen .trim()oder in einem nullFall einen Standardwert festlegen möchten , verwenden wir den Parameter meistens wieder, da die Einführung einer neuen Variablen in solchen Fällen weniger lesbar ist als die Wiederverwendung des Parameters.

Sie sollten einen Parameter wirklich nicht wiederverwenden, um einen ganz anderen Inhalt zu speichern, da der Name nicht mehr auf seinen Inhalt verweist. Dies gilt jedoch für jede Neuzuordnung einer Variablen und ist nicht auf Parameter beschränkt.

Setzen Sie sich also mit Ihrem Team zusammen und formulieren Sie Kodierungskonventionen, die diese Angelegenheit abdecken.

MrSmith42
quelle
0

Wenn Sie aus Sicherheitsgründen eine statische Codeanalyse verwenden, kann dies zu Verwirrung führen und Sie denken, dass Sie die Eingabeparametervariable vor der Verwendung nicht validiert oder bereinigt haben. Wenn Sie sie beispielsweise Namein einer SQL-Abfrage verwenden, wird möglicherweise eine SQL-Injection-Sicherheitsanfälligkeit gemeldet, die Sie Zeit bei der Erläuterung kosten würde. Das ist schlecht. Auf der anderen Seite ist die Verwendung einer eindeutig benannten Variablen für die bereinigten Eingaben, ohne die Eingaben tatsächlich zu bereinigen, eine schnelle Möglichkeit, naive Codeanalysatoren zu stillen (falsch-negative Schwachstellenerkennung).

Greg
quelle
In den meisten Fällen können Sie auch eine Anmerkung oder einen speziellen Kommentar verwenden, um dem Codeanalysator anzuzeigen, dass dies beabsichtigt ist und kein unbemerktes Risiko darstellt.
MrSmith42
0

Die Antwort darauf hängt zu 100% davon ab, wer Ihren Code lesen wird. Welche Stile finden sie am hilfreichsten?

Ich habe festgestellt, dass der allgemeinste Fall darin besteht, dass man das Zuweisen von Werten zu Funktionsargumenten vermeidet, weil zu viele Entwickler über mentale Modelle verfügen, wie Funktionsaufrufe funktionieren, bei denen davon ausgegangen wird, dass Sie dies niemals tun. Dieses Problem kann durch Debugger verstärkt werden, die die Werte der Argumente ausgeben, mit denen Sie die einzelnen Funktionen aufrufen. Diese Informationen sind technisch nicht korrekt, wenn Sie die Argumente bearbeiten. Dies kann zu seltsamen Frustrationen führen.

Davon abgesehen ändern sich die mentalen Modelle. In Ihrer speziellen Entwicklungsumgebung kann es wünschenswert sein name, "zu diesem Zeitpunkt die beste Darstellung des Namens zu haben ". Es kann wünschenswert sein, die Variablen, an denen Sie arbeiten, expliziter mit ihren Argumenten zu verknüpfen, auch wenn Sie unterwegs einige Änderungen an ihren Werten vorgenommen haben. Die Wiederverwendung bestimmter Variablen kann sogar erhebliche Laufzeitvorteile mit sich bringen, anstatt sperrigere Objekte zu erstellen. Wenn Sie mit 4-GB-Zeichenfolgen arbeiten, ist es schließlich hilfreich, die Anzahl der zusätzlichen Kopien zu minimieren, die Sie erstellen müssen!

Cort Ammon
quelle
-1

Ich habe ein völlig anderes Problem mit Ihrem Codebeispiel:

Der Name Ihrer Methode lautet SanitizeName. In diesem Fall erwarte ich, dass ein Name bereinigt wird . denn das ist, was du dem Leser von deiner Funktion sagst.

Das Einzige , was Sie tun sollten , ist, einen bestimmten Namen zu bereinigen . Ohne Ihren Code zu lesen, würde ich Folgendes erwarten:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

Aber Sie implizieren, dass Ihre Methode ein bisschen mehr als nur das Desinfizieren leistet. Das ist ein Codegeruch und sollte vermieden werden.

Ihre Frage bezieht sich nicht auf: Ist es eine schlechte Praxis, Methodenparameter wiederzuverwenden? Es ist mehr: Sind Nebenwirkungen und unerwartetes Verhalten schlechte Praxis?

Die Antwort darauf lautet eindeutig: Ja!

Dies ist rein harmlos, da das Argument Name nicht als Referenz übergeben wird. Wenn jedoch ein Entwickler in Zukunft aus irgendeinem Grund entscheidet, dass alle Werte per ref übergeben werden, wirkt sich eine Bereinigung des Strings auf den Wert außerhalb der Methode aus, was zu nachteiligen Ergebnissen führen kann

Sie führen Ihren Leser in die Irre, indem Sie nichts zurückgeben. Ihr Methodenname zeigt deutlich an, dass Sie etwas tunName . Wohin soll das Ergebnis gehen? Durch deine Funktionsunterschrift voidlese ich Name, tue aber weder Schaden an id, noch erzähle ich dir über das Ergebnis (explizit). Vielleicht gibt es eine Ausnahme, vielleicht auch nicht; wird aber Namenicht verändert . Dies ist die zu Ihrem Methodennamen entgegengesetzte Semantik.

Das Problem ist weniger die Wiederverwendung als die Nebenwirkungen . Um zu verhindern , Nebenwirkungen nicht wieder verwenden eine Variable. Wenn Sie keine Nebenwirkungen haben, gibt es kein Problem.

Thomas Junk
quelle
4
-1 Dies beantwortet nicht die ursprüngliche Frage. Der bereitgestellte Code ist nur ein Beispielcode zum Anzeigen der vorliegenden Frage. Bitte beantworten Sie die Frage, anstatt den bereitgestellten Beispielcode "anzugreifen" / zu überprüfen.
Niklas H
1
@NiklasH Dies beantwortet die Frage perfekt: Wenn Sie den Parameter innerhalb der Funktion manipulieren und, wie im TO erwähnt, versehentlich mit einer Referenz anstelle einer Kopie arbeiten, führt dies zu Nebenwirkungen (wie gesagt) und dies ist schlecht. Um dies zu verhindern, geben Sie an, dass Sie die Variable ändern möchten, indem Sie den Methodennamen sorgfältig auswählen (denken Sie an Rubys '!') Und / oder einen Rückgabetyp auswählen. Wenn Sie die Variable nicht ändern, arbeiten Sie nur mit Kopien.
Thomas Junk