2012-10-02 80 views
4

我不認爲它是可能的,但是你可以做類似的事情來允許通過類型擴展自定義格式嗎?可以將StructuredFormatDisplayAttribute作爲擴展方法的一部分使用

[<StructuredFormatDisplayAttribute("Rate: {PrettyPrinter}")>] 
type Rate with 
    member x.PrettyPrinter = x.Title + string x.Value 

注:這看起來是儘可能的內在擴展(同組裝),而不是作爲一個可選擴展

如果不是,我猜這可能是一個功能請求,除非任何人有一個很好的選擇?

回答

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 
+0

可惜不能將打印機添加到標準控制檯。 – 7sharp9

+0

我不確定你的意思。你可以發送任何你想要標準輸出。在該上下文中沒有_default類型的顯示。 – Daniel

+0

我的意思是說擴展標準打印機也不錯。 Printf.AddPrinter(fun(x:Rate) - > x.Title + string x.Value) – 7sharp9

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)。這使您可以使用用於在調試器中顯示類型的代理類型替換原始類型。 (但我認爲該屬性仍然必須放在實際的類型定義上,而不是擴展名上。)

+0

這不僅僅適用於正常控制檯輸出的調試。我檢查過,屬性必須放在實際的類型定義上,儘管實際的漂亮打印代碼可以放在擴展名中,也可以放在模塊中。 – 7sharp9