F#Interactive - 当后者可枚举时,如何使其打印对象的属性

时间:2013-08-21 13:01:06

标签: f# f#-interactive

在示例中显示更容易。如果我将以下内容发送给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中还有其他属性,特别是CountCapacity。 (这对于列表来说并不重要,但在我的情况下它适用于复杂类型)

如何使F#交互式打印出对象的属性并将其忽略为IEnumerable(就像第一个示例中的类型Person一样)< / p>

2 个答案:

答案 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