在示例中显示更容易。如果我将以下内容发送给F#interactive
type Person = {Name : string; Age : int}
let joe = {Name = "Joe"; Age=30}
输出结果为:
type Person =
{Name: string;
Age: int;}
val joe : Person = {Name = "Joe";
Age = 30;}
Fsi非常聪明,可以打印所有属性。
逐行发送以下内容
let l = new List<int>()
l
结果
val l : List<int>
val it : List<int> = seq []
Fsi看到l
实现IEnumerable
,并且(正确地)认为这是我期望看到的。但l
中还有其他属性,特别是Count
和Capacity
。 (这对于列表来说并不重要,但在我的情况下它适用于复杂类型)
如何使F#交互式打印出对象的属性并将其忽略为IEnumerable
?(就像第一个示例中的类型Person
一样)< / p>
答案 0 :(得分:7)
您可以使用fsi.AddPrinter
提供自定义打印机。它需要一个指定如何格式化特定类型的函数 - 我不认为有一种简单的方法可以执行此操作,但在这种情况下您可以使用非泛型IEnumerable
。以下内容使用默认打印打印序列,并添加Count
:
fsi.AddPrinter(fun (en:System.Collections.IEnumerable) ->
let count = Seq.cast<obj> en |> Seq.length
sprintf "%A { Count = %d }" en count
)
例如:
> l;;
val it : List<int> = seq [] { Count = 0 }
> seq { 1 .. 100000 };;
val it : seq<int> = seq [1; 2; 3; 4; ...] { Count = 100000 }
有趣的是,这也改变了字符串的打印,但只有在en
值不是字符串类型时才添加自定义属性,可以避免这种情况。
> "hello";;
val it : string = "hello" { Count = 5 }
答案 1 :(得分:1)
如果您覆盖.ToString
方法,则fsi将使用该方法。你也可以使用
[<StructuredFormatDisplay>]
属性,如果只想影响FSI