Optionaler Parameter Konstruktor mit Wert aus Klassenvariable

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    @RodFromGermany meinst Du so?

    C#-Quellcode

    1. static int _nextFreeStaffNumber = 0;
    2. static void GetNextFreeStaffNumber(int staffnumber)
    3. {
    4. if(staffnumber == _nextFreeStaffNumber)
    5. {
    6. throw new ApplicationException("Sorry, This Staffnumber is already in use!");
    7. }
    8. else
    9. {
    10. _nextFreeStaffNumber++;
    11. staffnumber = _nextFreeStaffNumber;
    12. }
    13. }


    Wie rufe ich denn diese ab BEVOR der Konstruktor aufgerufen wird???
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    Wie rufe ich denn diese ab BEVOR der Konstruktor aufgerufen wird???
    Mach da ne bool-Function draus:

    C#-Quellcode

    1. static int _nextFreeStaffNumber = 0;
    2. static bool CheckStaffNumber(int staffnumber)
    3. {
    4. if(staffnumber == _nextFreeStaffNumber) // eigentlich sollten hier alle bisher in Benutzung stehenden Nummern abgetestet werden.
    5. {
    6. return false;
    7. }
    8. return true;
    9. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany wenn alle jemals benutzten abgeprüft werden sollten (macht ja auch sinn) dann pack ich die Nummern besser zusätzlich in eine List(of int), bzw. Wandel die int Variable in ne List(of int) um, dann könnte ich die 1. besser abspeichern und 2. alle nummern in einer For oder foreach schleife prüfen...
    "Hier könnte Ihre Werbung stehen..."
    mangels Beispielprojekt bin ich nicht 100% sicher, aber ich glaub, dass die von dir gewünschte Funktionalität auch mit optionalen Parametern umsetzbar wäre.
    Ich sag jetzt nicht, das sei besser oder schlechter, nur, dass du aus diesem Thread nicht eine Vermeidungshaltung gegenüber optionalen Parametern davonträgst.
    @ErfinderDesRades deswegen sprach @~blaze~ vermutlich auch von Interlocked, wo ich aber die Verwendung nicht so recht verstehe.
    ich kann nachher mal die Klasse mit ner Konsolenanwendung bauen und hoch laden... im Moment reis ich Tapeten ab...

    EDIT: wobei ich mir gerade denke, das ich wohl eher die staffnumber als Parameter mache, der in jedem Fall gesetzt werden muss, dann muss sich eben der Anwender darum kümmern da was sinnvolles zu übergeben.
    "Hier könnte Ihre Werbung stehen..."
    Interlocked hat mit dem optionalen Parameter nichts zu tun. Du könntest ihn durch Nullable einführen, aber das finde ich ein wenig hässlich, wenn es nicht ausdrücklich eine derartige Funktionalität geben soll.

    Interlocked kannst du so verwenden:

    C#-Quellcode

    1. private static int _nextFreeMember;
    2. private static int GetNextFreeMember()
    3. {
    4. //führt in einem Schritt den Increment durch und weist das Ergebnis _nextFreeMember zu. Anschließend wird nochmal 1 abgezogen, damit _nextFreeMember bei 0 beginnt.
    5. return System.Threading.Interlocked.Increment(ref _nextFreeMember) - 1;
    6. }


    Du erhältst damit eine threadsichere "atomare" Operation. Da das Erhöhen des Wertes einer Variablen den Operationen Read-Add-Write (z.B. mit Variablen a: READ a, a := a + 1, WRITE a) entspricht, können sich zwei Threads gegenseitig in die Quere kommen, wenn der Thread das Ergebnis des ersten Threads nicht berücksichtigt, da es schon davor liest. Das Problem tritt dann zumeist nur in wenigen Fällen auf und ist schwer nachzuvollziehen.
    Interlocked führt solche operationen dann eben atomar aus, d.h. die Operation wird auf jeden Fall in einem Schritt abgeschlossen, sodass andere Threads nicht währenddessen lesen oder schreiben können.

    Statische Variablen sind nicht an eine Instanz gebunden. Wenn ein Member nicht statisch ist (abgesehen vom Konstruktor), kann er nur auf Instanzen aufgerufen werden. Andererseits sind alle Felder (und auch alles, was nicht-statische Felder kapselt, wie Events ohne manuell definierte add- und remove-Operation, usw.) dann für diese Instanz spezifisch festgelegt, d.h. Änderungen sind natürlich nicht übergreifend zwischen den einzelnen Instanzen. Bei statischen Variablen ist das dann eben anders - allerdings verwenden alle Threads dann dieselben statischen Felder (außer, es wird das ThreadStaticAttribute darauf definiert) und somit können die Überschneidungen für Threads kritisch sein.

    Ach ja: Wenn die staff number nur inkrementiert wird, ist das mit dem Interlocked so möglich, ansonsten würde ich dir empfehlen, eine eigene Klasse anzulegen, die die Verwaltung der Zahlen vornimmt.
    Statt einer List<T> halte ich hier ein HashSet<T> für besser, die Überprüfung ist weitaus effizienter. Aber ich würde vielleicht auch das komplette Konzept mit inkrementierenden IDs überdenken und lieber auf GUID oder ein ähnliches Prinzip zurückgreifen. Dafür müsste man allerdings das komplette Szenario mitsamt den Anforderungen und Problemen kennen.

    Viele Grüße
    ~blaze~

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „~blaze~“ ()

    @MichaHo Ich würde die StaffNumber überhaupt aus dem Parametersatz streichen und immer die nächste verfügbare verwenden.
    Feddich. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany ja, so werd ich es auch machen, ich wollte es halt für unsere ATler machen, die haben ja bereits eine Nummer, aber dann regel ich da bei denen über den Namen... wird ja denn eh von jedem selbst benutzt und läuft nicht auf irgendeinem server...
    "Hier könnte Ihre Werbung stehen..."