Rouven: C# - Was zurückgeben für int = null?

Hallo,

ich habe vor einigen Tagen mit C# im Zusammenhang mit ASP.NET angefangen. Jetzt schreibe ich mir hier gerade einige Methoden mit denen ich Werte aus einer Datenbank auslese. Von Java bin ich gewöhnt, wenn ich das Ergebnis nicht finden kan, gebe ich halt null zurück.
Jetzt habe ich eine Funktion:
public static int getInt(...) {
   if (...)
      return int.Parse(...);
   else
      ???
}
Bei den ??? stoße ich auf das Problem. Ich möchte zurückgeben "da ist kein passender Wert", wie ist die bevorzugte Variante von C#? Bei return null beschwert er sich, dass null und int nicht kompatibel seien...

MfG
Rouven

--
-------------------
ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
  1. Hi,

    ich habe vor einigen Tagen mit C# im Zusammenhang mit ASP.NET angefangen.

    ich sollte erwähnen, dass ich mit C# noch gar keine Erfahrung habe.

    Von Java bin ich gewöhnt, wenn ich das Ergebnis nicht finden kan, gebe ich halt null zurück.

    In vielen Fällen ist es da besser, eine Exception zu schmeißen.

    Bei den ??? stoße ich auf das Problem. Ich möchte zurückgeben "da ist kein passender Wert", wie ist die bevorzugte Variante von C#?

    Hat C# ein adäquates Exception-Handling?

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Morgen!

      In vielen Fällen ist es da besser, eine Exception zu schmeißen.

      Ja, macht bestimmt auch Sinn. Nur wenn ich von einer Datenbank in ein Objekt übersetze ist das nicht wirklich förderlich. Ich muss nunmal irgendwie rüberbringen "ja, es gibt dieses Attribut, aber es ist null". Ich werde wahrscheinlich auf die .MinValue-Lösung ausweichen.

      Hat C# ein adäquates Exception-Handling?

      Ja, hat es.

      MfG
      Rouven

      --
      -------------------
      ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
  2. Hallo,

    Bei return null beschwert er sich, dass null und int nicht kompatibel seien...

    Das funktioniert tatsächlich nicht. Datentypen wie int, float usw. können nicht NULL sein.
    An sich solltest Du, wie Cheatah schon angedeutet hat, eine Exception schmeissen bzw. diese vom Framework selbst schmeissen lassen (System.Int32.Parse() bzw. Convert.ToInt32() würde entsprechende Exceptions schmeissen, wenn der string nicht konvertiert werden kann).
    Natürlich ist das für den Programmfluss nicht gerade nützlich, wenn man bei jeder Zuweisung/Umwandlung mit einer Exception rechnen muss, aber auf NULL müsstest Du auch reagieren, also könntest Du auch einen try-catch-Block im Aufrufenden Code verwenden, oder Du machst z.B. folgendes:

    public static int getInt(string input, int defaultValue)
    {
       if (...)
          return int.Parse(...);
       else
          return defaultValue;
    }

    Dann kannst Du ja einen an sich ungültigen Wert als defaultValue übergeben und wenn der dann zurückgegeben wird, entsprechend darauf reagieren.

    Grüße
      Klaus

    1. Hi,

      das mit dem Default-Value von int.MinValue war meine aktuelle Lösung, aber wenn ich "null" von der Tipplänge daneben stelle, komme ich gerade bis "int.", da fand ich null irgendwie praktischer. Das mit der Exception ist eher unangebracht. Im konkreten Fall geht es darum, dass in der Datenbank entweder ein int oder null steht, und dafür suchte ich eine adäquate Übersetzung...

      MfG
      Rouven

      --
      -------------------
      ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
    2. Hallo,

      es ist nicht sonderlich sinnvoll Exceptions der Runtime zu provozieren.

      Darüber hinaus gibt es mittlerweile "nullable types" (.Net 2.0).
      Nebenbei bemerkt könnte man soetwas auch "erfinden" (so quasi künstlich
      für seine eigenen Zwecke).

      Von daher ist das Thema "defaultValue" nicht gerade dumm.

      Frank (der gerade irgendwie enttäuscht von seiner Arbeitsumgebung ist)

  3. Hallo Rouven,

    Ich habe mit C# noch nicht gearbeitet, aber auch in Java ist es ja so, dass nur Referenz-Typen den Wert null haben können.
    Gibt es in C# nicht auf zu jedem nativen Typ eine Klasse also z.B. Integer für int wie in Java?

    Wenn es so etwas nicht gibt, könntest Du eigene Klassen für SQL-Datentypen verwenden. Das könnte ohnehin sinnvoll sein.

    Grüße

    Daniel

    1. Hi,

      das mit den eigenen Typen für die SQL-Typen wäre natürlich eine Möglichkeit, aber ich versuche gerade eine saubere Trennung zwischen Präsentation-Verarbeitung-Daten hinzubekommen, so dass die Präsentationsschicht nichts von den Datenstrukturen weiß. Insofern wollte ich sie eigentlich auch von Datenbank-Eigenheiten fernhalten...

      MfG
      Rouven

      --
      -------------------
      ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
      1. Sup!

        Präsentationsschicht

        ...ist ein Wort, das im IT-Bullshit-Bingo nicht fehlen darf.

        Whatever - ich hoffe mal, Deine Anwendung ist nicht eine solche, wo zwar die ganzen Schichten "überhaupt nichts" von den Daten und ihren Strukturen wissen - aber alle Schichten dennoch aufgrund ihrer Auslegung implizit ausschließlich für die Präsentation, Verarbeitung und Speicherung genau dieser Daten geeignet sind, womit das ganze Prinzip ziemlich ad absurdum geführt wird; die gibt es nämlich häufig.

        Gruesse,

        Bio

        --
        Never give up, never surrender!!!
        1. Hi,

          na ja, als ich das ganze das erste mal gehört habe, hab ich auch nicht viel davon gehalten. Mittlerweile hab ich einige Bücher und ein paar Beispielimplementierungen gesehen und bin von derartig strukturierten Systemen einigermaßen überzeugt. Die Trennung von Inhalt und Darstellung, das predigen wir hier doch alle jedes Mal auf's neue mit CSS und "sauberem" HTML. Nun geht das ganze doch nur noch einen Schritt weiter: Wir trennen auch noch Verarbeitunsroutinen von den reinen Datenroutinen, in meinem Fall bedeuted das C# Klassen vs. Stored Procedures im SQL-Server. Es geht den SQL-Server weder was an, welche Fehler hier wann nach außen geworfen werden noch welche Checks und Meldungen der Reihe nach ablaufen bevor irgendein Vorgang abläuft. Anders herum kann es der C#-Klasse relativ egal sein, ob ein Feldwert jetzt über dies oder jenes SQL-Statement rausgekommen ist, das ist Sache des Daten(-bank)-Modells in dem die Daten langfristig liegen, was nichts mit der Verarbeitung zu tun hat.

          Ist 3-Tier ein IT-Schlagwort? Sicherlich.
          Macht 3-Tier Sinn? IMHO ebenfalls sicherlich.*

          MfG
          Rouven

          *Natürlich nicht unbedingt für eine einzelne kleine Webseite, aber wenn man ein größeres System baut schon.

          --
          -------------------
          ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
          1. Hi,

            schön, ganz toll gesagt!

            Nur mal ganz nebenbei, welcher C# Klasse kann Was egal sein?

            Und du hast was gelesen, hast ein Beispiel gesehen. Aber du hast es noch nie selbst gemacht? Das ist gut, du solltest einen Management-Posten bekommen.

            Ciao, Frank

            1. Morgen!

              Nur mal ganz nebenbei, welcher C# Klasse kann Was egal sein?

              Der C#-Klasse meiner "Geschäftslogik".

              Und du hast was gelesen, hast ein Beispiel gesehen. Aber du hast es noch nie selbst gemacht? Das ist gut, du solltest einen Management-Posten bekommen.

              Herzlichen Dank. Dann verdiene ich wenigstens gutes Geld... Davon mal ab: Womit fängst du an? Mit einem Zufallsgenerator eine Zeichenfolge generieren und auf "Compile" drücken? Ich habe mir zwei Bücher angeschaut, in denen mit der beschriebenen Architektur ein Online-Shop aufgesetzt wurde. Eigentlich interessierte mich die Grundarchitektur von .NET, aber durch das Buch bot sich die Gelegenheit sich auch so eine Dreistufen-Architektur mal anzuschauen. Was mache ich jetzt? Ich nutze das, was ich gelesen habe, um es in meiner eigenen Projekt umzusetzen - natürlich erstmal im kleinen. Bei meiner aktuellen Seite bräuchte ich nie im Leben eine solche Architektur, aber woran soll man eine sinnvolle Aufteilung lernen wenn nicht durch solche kleinen Sachen.
              Was glaubst du, warum ich die Frage stelle wie sowas geht? Meinst du ich bin Projektmanager und möchte gerade einen Programmierer zur Sau machen, warum seine Klasse nicht null zurückgibt?

              MfG
              Rouven

              --
              -------------------
              ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
            2. Ach ja, und nachdem ich mich jetzt gerade wieder etwas beruhigt habe, den Hinweis mit den nullable Types als Antwort auf Klaus Mock hätte ich als Antwort/Suchstichwort sehr hilfreich gefunden... Also, danke dir trotzdem, damit kann ich jetzt weitermachen.
              Falls es das Archiv interessiert:
              C#-.NET 2.0 - nullable types

              MfG
              Rouven

              --
              -------------------
              ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
          2. Hallo Rouven,

            Die Präsentationsschicht sollte schon davon unabhängig sein, wo die darzustellenden Daten herkommen. Davon, wie die darzustellenden Daten aussehen, kann sie aber nicht unabhängig sein. Du kannst so etwas natürlich erreichen indem Du die Daten erst nochmal konvertierst und das SQL-NULL z.B. durch einen Default-Wert ersetzt o.ä.
            Das hast Du aber anscheinen nicht vor. Wenn es nun also Wertebereiche gibt, mit denen die Präsentationsschicht klar kommen musst, kannst Du diese Typen auch ganz klar in Klassen abbilden. Damit koppelst Du Deine Präsentationsschicht nur an die Struktur der Daten.
            Wenn Du das nicht willst, kannst Du die Schnittstelle natürlich auch so definieren, dass ein Stück weit von den SQL-Datentypen abstrahiert wird. Es bleibt aber dabei, dass Du einen Integer-Typ hast, der auch den Wert "unbekannt" haben kann.

            Du hast mir vorhin nicht auf die Frage geantwortet, ob es in C# auch eine Klasse für Integers gibt. Das würde Dein Problem nämlich auch lösen.

            Grüße

            Daniel

            1. Morgen!

              So, jetzt guck ich doch das ganz wirklich mal nach. Also, wieder was gelernt, nachfolgende Passagen als Kurzversion von Datentypen in C# (ASPHEUTE)
              So wie Java auch, unterscheidet C# zwischen simple types und reference types. Erstere sind u.a. die Basistypen wie int, float etc. sowie structs, untere reference types fällt alles was irgendwie nach Objekt klingt.
              Sehr gut gefällt mir nun die Umschreibung "Es ist zwar alles ein Objekt, aber nur dann wenn es eines sein muß."
              Man _kann_ einen int in ein Objekt packen "boxing", damit kann man dieses object auf null setzen. Ich kann auch den Wert dieses Objektes verändern, was _nicht_ den Wert meines ursprünglichen ints verändert (unabhängige - ähm - nennen wir sie mal Objekte).
              Durch ein simples casten auf einen (int) verwandelt man das Objekt wieder in sein simple-type-Äquivalent zurück.

              Simple-Types müssen _immer_ einen Wert haben, während Reference-Types null sein dürfen.

              Interessantes Konzept, klingt lästig...

              MfG
              Rouven

              --
              -------------------
              ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
          3. Sup!

            na ja, als ich das ganze das erste mal gehört habe, hab ich auch nicht viel davon gehalten. Mittlerweile hab ich einige Bücher und ein paar Beispielimplementierungen gesehen und bin von derartig strukturierten Systemen einigermaßen überzeugt. Die Trennung von Inhalt und Darstellung, das predigen wir hier doch alle jedes Mal auf's neue mit CSS und "sauberem" HTML. Nun geht das ganze doch nur noch einen Schritt weiter: Wir trennen auch noch Verarbeitunsroutinen von den reinen Datenroutinen, in meinem Fall bedeuted das C# Klassen vs. Stored Procedures im SQL-Server. Es geht den SQL-Server weder was an, welche Fehler hier wann nach außen geworfen werden noch welche Checks und Meldungen der Reihe nach ablaufen bevor irgendein Vorgang abläuft. Anders herum kann es der C#-Klasse relativ egal sein, ob ein Feldwert jetzt über dies oder jenes SQL-Statement rausgekommen ist, das ist Sache des Daten(-bank)-Modells in dem die Daten langfristig liegen, was nichts mit der Verarbeitung zu tun hat.

            Ist 3-Tier ein IT-Schlagwort? Sicherlich.
            Macht 3-Tier Sinn? IMHO ebenfalls sicherlich.*

            Ich hab' nurmal gesehen, wie bei einem kleineren Projekt Leute so ein System designt haben; Datenstruktur, Geschäftslogik und Präsentationsschicht hingen dabei so weitgehend zusammen, dass sie immer, wenn Ihnen eingefallen ist, dass auf Ebene der Präsentationsschicht noch etwas zusätzlich angezeigt werden sollte, alle drei Ebenen ändern mussten; das mag heute mit einem vernünftigen IDE und "Refactoring" nicht mehr so schlimm sein wie "damals"; ist aber dennoch nervig.
            Sowieso ist Code-Reuse (warum sonst sollte man trennen) weitgehend ein Mythos, wenn man von Bibliotheken absieht.

            Gruesse,

            Bio

            --
            Never give up, never surrender!!!
            1. Hi,

              Ich hab' nurmal gesehen, wie bei einem kleineren Projekt Leute so ein System designt haben; Datenstruktur, Geschäftslogik und Präsentationsschicht hingen dabei so weitgehend zusammen, dass sie immer, wenn Ihnen eingefallen ist, dass auf Ebene der Präsentationsschicht noch etwas zusätzlich angezeigt werden sollte, alle drei Ebenen ändern mussten; das mag heute mit einem vernünftigen IDE und "Refactoring" nicht mehr so schlimm sein wie "damals"; ist aber dennoch nervig.

              Das stimmt wahrscheinlich je nach Design und die Sache mit dem Refactoring hilft dabei auch nur begrenzt.

              Sowieso ist Code-Reuse (warum sonst sollte man trennen) weitgehend ein Mythos, wenn man von Bibliotheken absieht.

              Das ist leider wahr. Wobei Code-Reuse die eine Sache ist, lass es mich mal "code-extension" nennen die andere. Gesetz den Fall man hat die Trennung sauber hinbekommen, dann sollte es ohne weiteres möglich sein das Layout der Seite komplett umzustellen ohne eine einzige Funktion der Schichten 2 und 3 anpacken zu müssen, man muss lediglich die Aufrufe an anderen Stellen platzieren.

              Ich denke auch, dass es in den Anfängen eines Projektes eher 3x so viel Arbeit macht wie ein einfaches 1 oder 2-Schichtenmodell und man, wie du schon sagst, ständig Funktionen an allen Stellen nachtragen musst. Die Frage ist nur, wen man sich jetzt überlegt "ich möchte xyz auch noch auf Seite 123 anzeigen", dann müsstest du ohne Umschreibeaufwand dran kommen.

              Aber gut, ich probier das halt alles mal aus, wenn es Quatsch ist kommt es in die Tonne, wenn es funktioniert umso besser.

              MfG
              Rouven

              --
              -------------------
              ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
              1. Sup!

                Aber gut, ich probier das halt alles mal aus, wenn es Quatsch ist kommt es in die Tonne, wenn es funktioniert umso besser.

                Dann hoffe ich mal das beste für Dich.

                Gruesse,

                Bio

                --
                Never give up, never surrender!!!
  4. Sup!

    Gibbet nicht sowas wie "NaN", "nil" oder sonstwas?

    Gruesse,

    Bio

    --
    Never give up, never surrender!!!
    1. Hallo.

      Gibbet nicht sowas wie "NaN", "nil" oder sonstwas?

      Nope, n/a -- kleiner Scherz.
      MfG, at