Повторяя сказанное Томасом, вы можете использовать цитаты, чтобы избежать дублирования. Но вместо ToLinqExpression -> ToString
, который, очевидно, создает исходный код C #, вы можете использовать мою библиотеку Unquote , которая создает строки исходного кода F #. Объедините это с реализацией, подходящей для производственного кода (т. Е. Определяя Assert
inline с ветвью символа компиляции, отличной от DEBUG
, испускающей только no-op ()
означает, что использование Assert
будет полностью удалено в non-DEBUG
сборка с включенной оптимизацией):
let inline Assert (q:Expr<bool>) =
#if DEBUG
System.Diagnostics.Debug.Assert(q.Eval(), q.Decompile())
#else
()
#endif
тогда выражение утверждения Assert <@ (22 + 2) / 2 = ("assert" |> String.length) @>
по умолчанию создает следующее всплывающее диалоговое окно (я думаю, вы можете настроить поведение System.Diagnostics.Debug
):
![enter image description here](https://i.stack.imgur.com/HVj2n.png)
Где для сравнения q.ToLinqExpression().ToString()
производит (((22 + 2) / 2) == op_PipeRight("assert", ToFSharpFunc(str => Length(str))))
.
Фактически, Unquote был разработан специально для создания полезных сообщений об ошибках подтверждения модульного теста и может быть легко адаптирован для отладки утверждений, создающих пошаговые сообщения об ошибках:
let inline Assert (q:Expr<bool>) =
#if DEBUG
System.Diagnostics.Debug.Assert(q.Eval(), q.ReduceFully() |> List.map (fun q -> q.Decompile()) |> String.concat System.Environment.NewLine)
#else
()
#endif
![enter image description here](https://i.stack.imgur.com/wi7v4.png)