我不认为它可能,但你可以做类似的事情,以允许通过类型扩展名进行自定义格式化吗?
[<StructuredFormatDisplayAttribute("Rate: {PrettyPrinter}")>]
type Rate with
member x.PrettyPrinter = x.Title + string x.Value
注意:它看起来可以作为内部扩展(相同的程序集),但不能作为可选扩展名。
如果不是,我猜这可能是一个功能请求,除非有人有一个不错的选择?
答案 0 :(得分:2)
不,这是不可能的。在FSI中,您可以使用fsi.AddPrinter
来自定义输出。
fsi.AddPrinter (fun (x: Rate) -> x.Title + string x.Value)
修改
对于常规字符串格式,您可以将Printf
与%a
格式说明符一起使用。一些额外的功能可以使这更方便。
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Rate =
let stringify (x: Rate) = x.Title + string x.Value
let print rate = printf "%s" (stringify rate)
printf "Rate: %a" (fun _ -> Rate.print) rate
let formattedString = sprintf "Rate: %a" (fun _ -> Rate.stringify) rate
答案 1 :(得分:2)
正如您所说,StructuredFormatDisplayAttribute
仅适用于编译为属性的成员(包括标准属性,相同的程序集扩展,但不包括扩展成员)。在封面下,使用反射访问它(如你所见,它也可以是私有的):
let getProperty (obj: obj) name =
let ty = obj.GetType()
ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance |||
BindingFlags.Public ||| BindingFlags.NonPublic),
null, obj, [| |],CultureInfo.InvariantCulture)
如果您需要这个用于调试目的,那么DebuggerTypeProxy
属性可能是另一种选择(请参阅MSDN documentation)。这允许您使用用于在调试器中显示类型的代理类型替换原始类型。 (但我认为该属性仍然必须放在实际的类型定义上,而不是放在扩展名上。)