Konstruktoren mit demselben Argumenttyp

7

Ich habe ein Person-Objekt mit zwei Konstruktoren - einer nimmt einen int (personId), der andere einen String (logonName). Ich möchte einen anderen Konstruktor, der eine Zeichenfolge (badgeNumber) nimmt. Ich weiß, dass das nicht möglich ist, aber es scheint, dass es eine gemeinsame Situation ist. Gibt es einen anmutigen Umgang damit? Ich nehme an, dies würde für jede überladene Methode gelten. Code:

%Vor%

... usw.

    
JasonS 27.08.2008, 20:39
quelle

12 Antworten

7

Sie könnten benutzerdefinierte Typen verwenden.

Erstellen Sie beispielsweise LogonName- und BadgeNumber-Klassen.

Dann sehen Ihre Funktionsdeklarationen wie ...

aus %Vor%

Eine solche Lösung bietet Ihnen möglicherweise einen guten Ort, um die Geschäftslogik beizubehalten, die für das Format und die Verwendung dieser Zeichenfolgen gilt.

    
Zack Peterson 27.08.2008, 20:41
quelle
18

Sie könnten vielleicht stattdessen Factory-Methoden verwenden?

%Vor%     
toolkit 27.08.2008 20:43
quelle
2

Sie haben vier Möglichkeiten, die ich mir vorstellen kann, von denen drei bereits von anderen benannt wurden:

  1. Gehen Sie auf die Fabrikroute, wie von mehreren anderen hier vorgeschlagen. Ein Nachteil ist, dass Sie keine konsistente Benennung durch Überladen haben können (sonst hätten Sie das gleiche Problem), also ist es oberflächlich weniger sauber. Ein weiterer, größerer Nachteil besteht darin, dass es die Möglichkeit einer direkten Zuweisung auf dem Stapel ausschließt. Bei dieser Vorgehensweise wird alles auf dem Heap zugewiesen.

  2. Benutzerdefinierte Objektwrapper. Dies ist ein guter Ansatz, und der, den ich empfehlen würde, wenn Sie bei Null anfangen. Wenn Sie viel Code verwenden, z. B. Badges als Strings, kann das Neuschreiben von Code dies zu einer nicht realisierbaren Option machen.

  3. Fügen Sie der Methode eine Aufzählung hinzu, und geben Sie an, wie die Zeichenfolge behandelt werden soll. Dies funktioniert, erfordert jedoch, dass Sie alle vorhandenen Aufrufe so umschreiben, dass sie die neue Enumeration enthalten (obwohl Sie bei Bedarf einen Standard angeben können, um dies zu vermeiden).

  4. Fügen Sie einen Dummy-Parameter hinzu, der nicht zur Unterscheidung der beiden Überladungen verwendet wird. z.B. Tack a bool auf die Methode. Dieser Ansatz wird von der Standardbibliothek an einigen Stellen, z.B. std::nothrow ist ein Dummy-Parameter für operator new . Die Nachteile dieses Ansatzes sind, dass es hässlich ist und dass es nicht skaliert.

Wenn Sie bereits eine große Basis an vorhandenem Code haben, würde ich empfehlen, entweder die Enumeration hinzuzufügen (möglicherweise mit einem Standardwert) oder den Dummy-Parameter hinzuzufügen. Weder ist schön, aber beide sind ziemlich einfach nachzurüsten.

Wenn Sie bei Null anfangen oder nur eine kleine Menge Code haben, würde ich die benutzerdefinierten Objektwrapper empfehlen.

Die Factory-Methoden wären eine Option, wenn Sie Code verwenden, der die rohen badge / logonName -Strings stark verwendet, aber nicht die Person -Klasse.

    
Derek Park 27.08.2008 21:08
quelle
2

Wenn Sie C # 3.0 verwenden, können Sie Objektinitialisierer verwenden:

%Vor%

Sie würden den Konstruktor wie folgt aufrufen:

%Vor%     
Jake Pearson 28.08.2008 12:57
quelle
1

Nein.

Sie könnten ein Flag-Feld (enum für Lesbarkeit) betrachten und dann den Konstruktor benutzen, um zu bestimmen, was Sie gemeint haben.

    
Craig 27.08.2008 20:41
quelle
1

Das wird nicht funktionieren. Sie könnten eine Klasse namens BadgeNumber erstellen, die eine Zeichenfolge umschließt, um diese Mehrdeutigkeit zu vermeiden.

    
Landon 27.08.2008 20:42
quelle
1

Sie können nicht zwei verschiedene Konstruktoren / Methoden mit der gleichen Signatur haben. Andernfalls kann der Compiler bestimmen, welche Methode ausgeführt werden soll.

Zack sagte , würde ich in Betracht ziehen, eine "Optionen" zu erstellen "Klasse, in der Sie die in einem benutzerdefinierten Typ enthaltenen Parameter tatsächlich übergeben können. Dies bedeutet, dass Sie so viele Parameter wie möglich übergeben können, und tun Sie, was Sie wollen mit den Optionen, seien Sie vorsichtig, dass Sie keine monolithische Methode erstellen, die alles versucht.

Entweder das oder wählen Sie das Werksmuster ..

    
Rob Cooper 27.08.2008 20:43
quelle
1

Sie können eine statische Factory-Methode verwenden:

%Vor%     
Outlaw Programmer 27.08.2008 20:44
quelle
1

Wie bereits erwähnt, sollten Sie in diesem Fall benutzerdefinierte Typen verwenden.

    
17 of 26 27.08.2008 20:46
quelle
0

Ich denke nur an das, was Sie tun wollen, ist params, eines, das den Param-Typ beschreibt (ein enum mit LogonName, BadgeNumer, usw.) und das zweite ist der param-Wert.

    
Ryan Farley 27.08.2008 20:42
quelle
0

Sie könnten zu einem Factory-Style-Muster wechseln.

%Vor%

Oder verwenden Sie, wie vorgeschlagen, benutzerdefinierte Typen. Sie können auch etwas mit Generics hacken, aber ich würde es nicht für die Lesbarkeit empfehlen.

    
Adam Wright 27.08.2008 20:44
quelle
-2

Wie wäre es ...

%Vor%     
Drakiula 27.08.2008 20:46
quelle

Tags und Links