2 Stimmen

Hinzufügen von Code im Konstruktor mit alternativer Klassensyntax

type Foo = 
    class
        inherit Bar

        val _stuff : int

        new (stuff : int) = {
            inherit Bar()
            _stuff = stuff
        }
    end

Ich möchte diesen Code im obigen Konstruktor hinzufügen:

if (stuff < 0) then raise (ArgumentOutOfRangeException "Stuff must be positive.")
else ()

Wie kann ich dies in F# erreichen?

5voto

kvb Punkte 54045

Sie können dies tun, ohne irgendwelche Workarounds zu benötigen, aber die Platzierung des anfänglichen linken curly ist ziemlich empfindlich (oder vielleicht ist der Parser fehlerhaft?). Um den Effekt zuerst zu machen:

type Foo =
  class
    inherit Bar
    val _stuff : int
    new (stuff : int) = 
      if stuff < 0 then raise (System.ArgumentOutOfRangeException("Stuff must be positive"))
      { 
        inherit Bar() 
        _stuff = stuff 
      }
  end

Um den zweiten Effekt zu erzielen:

type Foo =
  class
    inherit Bar
    val _stuff : int
    new (stuff : int) = 
      { 
        inherit Bar() 
        _stuff = stuff 
      }
      then if stuff < 0 then raise (System.ArgumentOutOfRangeException("Stuff must be positive"))
  end

4voto

Brian Punkte 115257

Hm, das sieht nach einer Lücke in der Grammatik aus; ich werde einen Vorschlag einreichen. Sie können es so umgehen:

type Bar() = class end

type Foo =     
    class        
        inherit Bar        
        val _stuff : int        
        private new (stuff : int, dummyUnused : int) = {            
            inherit Bar()            
            _stuff = stuff        
            }
        new (stuff : int) = 
            Foo(stuff, 0)
            then
                if (stuff < 0) then 
                    raise (System.ArgumentOutOfRangeException 
                             "Stuff must be positive.")
    end

wobei der erste Konstruktor ein Dummy ist, dessen einziger Zweck es ist, dem zweiten echten Konstruktor zu ermöglichen, ihn mit der Syntax "other-constructor then side-effect" aufzurufen.

Sie werden jedoch ein längeres und glücklicheres Leben führen, wenn Sie die

type Foo(_stuff:int) =     
    inherit Bar()
    do
        if (_stuff < 0) then 
            raise (System.ArgumentOutOfRangeException "Stuff must be positive.")

stattdessen. Verwenden Sie, wann immer möglich, Klassen mit Primärkonstruktoren. (Ein "primärer Konstruktor" ist der Konstruktor in der Klassendeklaration - im obigen Beispiel sind die Argumente unmittelbar nach "Typ Foo" die Konstruktorargumente, und alle let/do-Anweisungen innerhalb des Klassenkörpers definieren den primären Konstruktorkörper).

EDIT:

Hier ist eine viel einfachere Lösung

type Foo =     
    class        
        inherit Bar        
        val _stuff : int        
        new (stuff : int) = 
            let effect = 
                if (stuff < 0) then 
                    raise (System.ArgumentOutOfRangeException 
                            "Stuff must be positive.")
            {            
            inherit Bar()            
            _stuff = stuff        
            }
    end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X