F#は書式設定ディレクティブ "%A"を持っています。これは、型を拡張して個々のメンバーをリストするフォーマッタをトリガするので非常に強力です。私たちのアプリケーションのいくつかの場所では、ToStringメソッドを使用してデータを記録しています(それにはいくつかの技術的な理由があります)。そして、区別された共用体のような型の場合は、ログに記録される型名だけです。あまりにも悪いので、いくつかの型のToStringメソッドをオーバーライドし始めました。F#の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型の場合、 "%A"という書式設定ディレクティブを使用しようとするとToString呼び出しが発生するので、ToString自体にこのようなディレクティブが含まれていると失敗します。 ToStringオーバーライドの正しい方法は何ですか?そして、C#の種類の型(差別化された共用体とレコードは正常に動作しているようです)、または注意すべきことがありますか?
ありがとうございました! ToStringがF#のネイティブ型の方がより便利になるように改善されていることを知っておきましょう。 –