C # Syntax - Ihre bevorzugte Praxis, um 2 oder 3 Antworten von einer Methode zu erhalten

8

Ich frage mich nur, wie andere Entwickler dieses Problem lösen, indem sie von einer Methode zwei oder drei Antworten bekommen.

1) gebe ein Objekt zurück []
2) gebe eine benutzerdefinierte Klasse zurück 3) verwende ein out- oder ref-Schlüsselwort für mehrere Variablen 4) schreibe oder leihe (F #) ein einfaches Tupel & lt; & gt; generische Klasse
Ссылка

Ich arbeite gerade an Code, der Daten aktualisiert. Von der Methode, die die Aktualisierung durchführt, möchte ich zurückgeben (1) Refresh Startzeit und (2) Refresh End Time.
Zu einem späteren Zeitpunkt möchte ich vielleicht einen dritten Wert zurückgeben.

Gedanken? Irgendwelche guten Praktiken aus Open-Source-.NET-Projekten zu diesem Thema?

    
BuddyJoe 03.12.2008, 17:10
quelle

16 Antworten

5

Ihre Frage weist auf die Möglichkeit hin, dass Sie in Zukunft mehr Daten zurückgeben werden. Daher würde ich empfehlen, eine eigene Klasse zu implementieren, um die Daten zu enthalten.

Dies bedeutet, dass Ihre Methodensignatur unverändert bleibt, auch wenn die innere Repräsentation des Objekts, das Sie übergeben, sich ändert, um mehr Daten aufzunehmen. Es ist auch eine gute Übung für Lesbarkeit und Kapselung Gründe.

    
Dave R. 03.12.2008, 17:37
quelle
28

Es hängt ganz davon ab, was die Ergebnisse sind. Wenn sie miteinander verwandt sind, würde ich normalerweise eine benutzerdefinierte Klasse erstellen.

Wenn sie nicht wirklich verwandt sind, würde ich entweder einen out-Parameter verwenden oder die Methode aufteilen. Wenn eine Methode drei nicht verwandte Elemente zurückgeben möchte, tut das wahrscheinlich zu viel. Die Ausnahme ist, wenn Sie über eine Webservice-Grenze oder etwas anderes sprechen, bei dem eine "reinere" API zu geschwätzig ist.

    
Jon Skeet 03.12.2008 17:15
quelle
10

Für zwei, normalerweise 4)

Mehr als das, 2)

    
James Curran 03.12.2008 17:12
quelle
2

Code Architektur weise ich würde immer mit einer benutzerdefinierten Klasse gehen, wenn etwas eine bestimmte Menge an Variablen geändert werden muss. Warum? Ganz einfach, weil eine Klasse eigentlich ein "Bauplan" eines häufig verwendeten Datentyps ist. Wenn Sie also in diesem Fall einen eigenen Datentyp erstellen, erhalten Sie eine gute Struktur und können anderen beim Programmieren Ihrer Schnittstelle helfen.

    
Filip Ekberg 03.12.2008 17:19
quelle
2

Ich persönlich hasse out / ref params, also würde ich diesen Ansatz lieber nicht verwenden. Wenn Sie mehr als ein Ergebnis zurückgeben müssen, tun Sie wahrscheinlich meistens etwas falsches.

Wenn es wirklich unvermeidbar ist, werden Sie auf lange Sicht wahrscheinlich am glücklichsten sein, eine benutzerdefinierte Klasse zu schreiben. Die Rückgabe eines Arrays ist verlockend, da es in der kurzen Laufzeit einfach und effektiv ist, aber die Verwendung einer Klasse gibt Ihnen die Möglichkeit, den Rückgabetyp in der Zukunft zu ändern, ohne sich Sorgen machen zu müssen, dass im Nachhinein Probleme auftreten. Stellen Sie sich das Potenzial für einen Albtraum des Debuggens vor, wenn jemand die Reihenfolge von zwei Elementen in dem Array tauscht, das zurückgegeben wird ....

    
rotard 03.12.2008 18:20
quelle
1

Ich verwende out, wenn es nur 1 oder 2 zusätzliche Variablen gibt (zum Beispiel gibt eine Funktion ein bool zurück, das das eigentliche wichtige Ergebnis ist, aber auch einen out-Parameter, der angibt, wie lange die Funktion für Protokollierungszwecke ausgeführt wurde) .

Für etwas komplizierter, ich normalerweise eine benutzerdefinierte Struktur / Klasse erstellen.

    
Michael Stum 03.12.2008 17:13
quelle
1

Ich denke, die gängigste Methode, mit der ein C # -Programmierer das tun würde, wäre, die Elemente, die Sie zurückgeben wollen, in eine separate Klasse zu verpacken. Dies würde Ihnen die größte Flexibilität geben, IMHO.

    
Brian Sullivan 03.12.2008 17:14
quelle
1

Es kommt darauf an. Für eine nur interne API wähle ich normalerweise die einfachste Option. Im Allgemeinen ist das nicht möglich.

Für eine öffentliche API macht eine benutzerdefinierte Klasse normalerweise mehr Sinn - aber wenn es etwas ziemlich primitiv ist oder das natürliche Ergebnis der Funktion ein boolescher Wert ist (wie * .TryParse), bleibe ich bei einem out-Parameter. Sie können auch eine benutzerdefinierte Klasse mit impliziter Besetzung erstellen, aber das ist normalerweise nur komisch.

Für Ihre spezielle Situation erscheint mir eine einfache unveränderliche DateRange-Klasse am geeignetsten. Sie können diesen neuen Wert problemlos hinzufügen, ohne bestehende Benutzer zu stören.

    
Mark Brackett 03.12.2008 17:16
quelle
1

Wenn Sie die Anfangs- und Endzeiten der Aktualisierung zurücksenden möchten, deutet dies auf eine mögliche Klasse oder Struktur hin, möglicherweise DataRefreshResults genannt. Wenn Ihr möglicher dritter Wert auch mit der Aktualisierung zusammenhängt, könnte er hinzugefügt werden. Denken Sie daran, dass eine Struktur immer als Wert übergeben wird. Daher muss die Zuweisung auf dem Heap nicht durch Garbage-Collected erfolgen.

    
Frank Ames 03.12.2008 17:37
quelle
1

Manche Leute benutzen KeyValuePair für zwei Werte. Es ist jedoch nicht großartig, weil es nur die zwei Dinge als Key und Value bezeichnet. Nicht sehr beschreibend. Es würde auch sehr von dieser Ergänzung profitieren:

%Vor%

Erspart Ihnen das Festlegen der Typen, wenn Sie einen erstellen. Generische Methoden können auf Typen schließen, generische Klassenkonstruktoren hingegen nicht.

    
Daniel Earwicker 03.12.2008 20:05
quelle
1

Für Ihr Szenario möchten Sie möglicherweise eine generische Range {T} -Klasse definieren (mit Überprüfungen für die Bereichsgültigkeit).

Wenn die Methode privat ist, verwende ich normalerweise Tupel von meine Helferbibliothek . Öffentliche oder geschützte Methoden verdienen im Allgemeinen immer getrennt.

    
Rinat Abdullin 20.12.2008 12:18
quelle
1

Geben Sie einen benutzerdefinierten Typ zurück, aber verwenden Sie keine Klasse, verwenden Sie eine Struktur - keine Speicherzuweisung / Garbage-Collection-Overhead bedeutet keine Nachteile.

    
Mike Scott 20.12.2008 12:23
quelle
0

Wenn 2, ein Paar.

Wenn mehr als 2 eine Klasse.

    
John MacIntyre 03.12.2008 17:28
quelle
0

Eine andere Lösung besteht darin, ein Wörterbuch mit benannten Objektreferenzen zurückzugeben. Für mich entspricht das einer benutzerdefinierten Rückgabe-Klasse, aber ohne das Durcheinander. (Und mit RTTI und Reflexion ist es genauso sicher wie jede andere Lösung, wenn auch dynamisch.)

    
Jeff Kotula 03.12.2008 18:39
quelle
0

Es hängt von der Art und Bedeutung der Ergebnisse ab, ob die Methode privat ist oder nicht.

Für private Methoden verwende ich normalerweise nur ein Tupel aus meiner Klassenbibliothek.

Für public / protected / interne Methoden (dh nicht private) verwende ich entweder out-Parameter oder eine benutzerdefinierte Klasse.

Wenn ich zum Beispiel das TryXYZ-Muster implementiere, wo du eine XYZ-Methode hast, die eine Ausnahme bei einem Fehler auslöst, und eine TryXYZ-Methode, die Boolean zurückgibt, wird TryXYZ einen out-Parameter verwenden.

Wenn die Ergebnisse sequenzorientiert sind (dh 3 Kunden zurückgeben, die verarbeitet werden sollen), werde ich normalerweise eine Art von Sammlung zurückgeben.

Ansonsten verwende ich normalerweise nur eine benutzerdefinierte Klasse.

    
quelle
0

Wenn eine Methode zwei oder drei verwandte Werte ausgibt, würde ich sie in einem Typ gruppieren. Wenn die Werte nicht verwandt sind, ist die Methode wahrscheinlich viel zu viel und ich würde es in eine Reihe von einfacheren Methoden umgestalten.

    
Brian Rasmussen 20.12.2008 12:39
quelle

Tags und Links