F # имеет директиву форматирования «% A», которая очень эффективна, поскольку вызывает форматирование для расширения типов и перечисления отдельных членов. В некоторых местах в наших приложениях данные регистрируются с использованием метода ToString (для этого есть некоторые технические причины), а затем для типов, таких как дискриминационные объединения, это только имя типа, которое регистрируется. Слишком плохо, поэтому мы начали переопределять методы ToString для некоторых типов.Избегание переполнения стека при переопределении ToString в F #
Чтобы дать вам пример:
open System
type DiscrUnion =
| Text of string
let t1 = DiscrUnion.Text "text"
sprintf "%A" t1
sprintf "%s" <| t1.ToString()
type DiscrUnionWithToString =
| Text of string
override this.ToString() = sprintf "%A" this
let t2 = DiscrUnionWithToString.Text "text"
sprintf "%A" t2
sprintf "%s" <| t2.ToString()
DiscrUnion.ToString() печатается как "FSI_0003 + DiscrUnion", но DiscrUnionWithToString.ToString() я получаю фактические свойства: Текст «Текст ".
Пока все хорошо. Однако для типов CLR такое переопределение вызывает катастрофический результат: переполнение стека! Вот пример:
type PocoType() =
member val Text : string = null with get, set
let t3 = PocoType()
t3.Text <- "text"
sprintf "%A" t3
sprintf "%s" <| t3.ToString()
type PocoTypeWithToString() =
member val Text : string = null with get, set
override this.ToString() = sprintf "%A" this
let t4 = PocoTypeWithToString()
t4.Text <- "text"
sprintf "%A" t4
sprintf "%s" <| t4.ToString()
Даже не пытаться создать экземпляр PocoTypeWithToString. StackOverflowException.
Я понимаю, что для типа POCO попытка использовать директиву форматирования «% А» вызывает вызов ToString, поэтому, когда ToString сама содержит такую директиву, она потерпит неудачу. Но как правильно переопределить ToString? И должен ли я остерегаться только типов типов C# (дискриминационные союзы и записи, похоже, работают нормально), или есть другие вещи, о которых нужно знать?
Большое спасибо! Полезно знать, что ToString может быть улучшено, чтобы быть более полезным для родных типов F #. –