Переопределение Exception.Message / соответствие шаблону исключения - PullRequest
1 голос
/ 17 февраля 2011

Я пытаюсь сопоставить шаблон с исключением в его определении. Возможно ли что-то подобное следующему с использованием синтаксиса исключений F #, или я должен подкласс Exception?

Это то, что я ожидал работать:

exception CoordErr of int * int
    with
        override this.Message = 
            let CoordErr(x, y) = this
            sprintf "(%i %i)" x y //ERROR

Но выдает ошибки:

Значение или конструктор 'x' не определены
Значение или конструктор 'y' не определены

EDIT

Я также пытался добавить парены:

let (CoordErr(x, y)) = this

Но это дает ошибку:

Ожидается, что это выражение будет иметь тип exn, но здесь имеет тип CoordErr

UPDATE

Следующее работает, но не идеально:

exception CoordErr of int * int
    with
        override this.Message = 
            sprintf "(%i %i)" this.Data0 this.Data1

Есть ли другой способ сделать это?

ОБНОВЛЕНИЕ 2

Исходя из ответа kvb, я полагаю, что мог бы сделать следующее, чтобы проглотить предупреждение incomplete matches:

exception CoordErr of int * int
    with
        override this.Message = 
            match this :> exn with
            | CoordErr(x, y) -> sprintf "(%i %i)" x y
            | _ -> Unchecked.defaultof<_>

Ответы [ 3 ]

4 голосов
/ 17 февраля 2011

Ваша первая попытка не работает, потому что вы определяете функцию с привязкой let с именем CoordErr, которая скрывает конструктор исключений, а это не то, что вам нужно.

Ваша вторая попытка почти работает. К сожалению, определения исключений работают не совсем так, как распознаваемые объединения: когда сопоставление с шаблоном сопоставляется с конструктором исключения, соответствующее выражение должно иметь тип exn (а не определенный подтип исключения). В вашем случае вы пытаетесь сопоставить this (типа CoordErr) с конструктором CoordErr. Как это для обхода?

exception CoordErr of int * int
    with
        override this.Message = 
          let (CoordErr(x,y)) = upcast this
          sprintf "(%i %i)" x y
2 голосов
/ 19 августа 2016

Присвоение имен аргументам конструктора и доступ к соответствующим полям работает:

exception CoordErr of x : int * y : int
    with
        override this.Message = 
            sprintf "(%i %i)" this.x this.y

Я понимаю, что это не решение для сопоставления с шаблоном, но оно отвечает на часть "Overriding Exception.Message" вашего вопроса. :)

0 голосов
/ 05 мая 2013

Можно использовать сопоставление с шаблоном с учетом исключений для попытки с выражением

exception CoordErr of int * int
    with
        override this.Message = 
            try raise this with CoordErr(x, y) -> sprintf "(%i %i)" x y
...