private LambdaExpression fromEnumerableLambda(Type from)
{
var input = Ex.Parameter(from, "input");
var eType = from.GetTypeInfo().ImplementedInterfaces
.Where(i => i.GenericTypeArguments.Length == 1 && i.GetGenericTypeDefinition() == typeof(IEnumerable <>))
.Select(i => i.GenericTypeArguments[0]).SingleOrDefault()
?? from.GetTypeInfo().GenericTypeArguments[0];
var res = Ex.Parameter(typeof(string), "res");
var result = Ex.Block(new[] { res },
Ex.Assign(res, Ex.Call((from mi in typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Join))
where mi.GetGenericArguments().Length == 1
let par = mi.GetParameters()
where par.Length == 2 &&
par[0].ParameterType == typeof(string) &&
par[1].ParameterType == typeof(IEnumerable <>).MakeGenericType(mi.GetGenericArguments()[0])
select mi).Single().MakeGenericMethod(eType),
Ex.Constant(Separators[0].ToString()), input)),
Ex.Condition(Ex.MakeBinary(Et.Equal, Ex.Property(res, nameof(string.Length)), Ex.Constant(0)),
NoResult(typeof(string)),
Result(typeof(string), res)));
var block = Ex.Condition(Ex.MakeBinary(Et.Equal, input, Ex.Default(from)),
NoResult(typeof(string)),
result);
var lambda = Ex.Lambda(block, input);
return(lambda);
}