Добавление кода в конструктор с альтернативным синтаксисом класса - PullRequest
2 голосов
/ 17 ноября 2009
type Foo = 
    class
        inherit Bar

        val _stuff : int

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

Я хочу добавить этот код в конструктор выше:

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

Как мне добиться этого в F #?

Ответы [ 2 ]

5 голосов
/ 17 ноября 2009

Вы можете сделать это, не прибегая к каким-либо обходным путям, но расположение исходного левого фигурного куска довольно чувствительно (или, возможно, синтаксический анализатор содержит ошибки?). Чтобы сделать эффект первым:

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

Чтобы сделать второй эффект:

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
3 голосов
/ 17 ноября 2009

Хм, выглядит как дыра в грамматике; Я подам предложение. Вы можете обойти это так:

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

где первый конструктор является фиктивной, единственная цель которой - позволить второму реальному конструктору вызывать его с синтаксисом «другой конструктор, а затем побочный эффект».

Однако вы будете жить дольше и счастливее, если будете использовать

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

вместо этого. По возможности используйте классы с первичными конструкторами. («Первичный конструктор» является конструктором при объявлении класса - в приведенном выше примере аргументы, следующие сразу после «type Foo», являются аргументами конструктора, а любые let / Операторы do внутри тела класса определяют основное тело конструктора.)

EDIT:

Вот намного более простой обходной путь

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
...