4

在示例中显示更容易。如果我将以下内容发送到 F# 交互

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 看到了limplements IEnumerable,并且(正确地)认为这是我期望看到的。但在 中还有其他属性l,尤其是CountCapacity。(这对于列表并不重要,但在我的情况下对于复杂类型而言)

如何让 F# 交互式打印出对象的属性并忽略它IEnumerable(就像Person第一个例子中的类型一样)

4

2 回答 2

8

您可以使用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 }

有趣的是,这也改变了字符串的打印,但是您可以通过仅在envalue 不是字符串类型时添加自定义属性来避免这种情况。

> "hello";;
val it : string = "hello" { Count = 5 }
于 2013-08-21T13:38:11.783 回答
1

如果您覆盖该.ToString方法,fsi 将使用该方法。[<StructuredFormatDisplay>]如果只想影响 FSI,也可以使用该 属性

于 2013-08-21T13:40:20.257 回答