Интересно почему для match генерится такой не оптимальный код, например:
[Record]
public variant DecisionNode
{
| Condition
{
condition : GuardNode;
body : DecisionNode;
else_node : DecisionNode;
}
| Action
{
condition : option[GuardNode];
body : DecisionNode;
}
| Else
{
body : DecisionNode;
}
| Target
{
target : TransitionTarget;
destination : TransitionDestination;
}
}
public Fold[T](init : T,
cond : T * GuardNode * Condition -> T,
els : T * Else -> T,
targ : T * TransitionTarget * TransitionDestination * Target -> T,
act : T * option[GuardNode] * DecisionNode.Action -> T) : T
{
def loop(e, acc, cont)
{
match (e)
{
| Target(x, d) as t => cont(targ(acc, x, d, t))
| Condition(c, b, e) as t => loop(b, acc, bacc =>
loop(e, bacc, eacc =>
cont(cond(eacc, c, t))))
| Else(b) as t => loop(b, acc, bacc => cont(els(bacc, t)))
| Action(c, b) as t => loop(b, acc, bacc => cont(act(bacc, c, t)))
}
}
loop(this, init, x => x)
}
здесь обычный перебор веток варианта в match, в рефлекторе он генерит такой код:
if (!(e is Condition))
{
if (!(e is Action))
{
if (!(e is Else))
{
if (!(e is Target))
{
throw new MatchFailureException();
}
Target t = (Target) e;
int x = ((Target) e).target;
int d = ((Target) e).destination;
return e_._N_cont_4406.apply(_N_xnode_4367(_N_FoldThis_cp_4381._N_targ_4361.apply(x, d, t), null, null, t));
}
то есть он смотрит оператором is те ли это типы, не проще ли использовать _N_GetVariantCode(), и по нему узнавать что это за экземпляр?