Expression trees seem to build an unnecessary conversion when working with bytes and shorts, they convert both sides (in binary expressions for instance) to int32.
This
That's really interesting; unfortunately, the rules of the expression-tree compiler are not formally specified - there is a brief "are elsewhere" in the specification, but : they aren't really.
If it is causing a problem, you could try to spot and remove it - something like below, which is 100% untested and use-at-own-risk, etc:
static void Main()
{
Console.WriteLine(((Expression>)((s, s1) => s == s1)).Unmunge());
Console.WriteLine(((Expression>)((s, s1) => s == s1)).Unmunge());
}
static Expression Unmunge(this Expression expression)
{
return (Expression)RedundantConversionVisitor.Default.Visit(expression);
}
class RedundantConversionVisitor : ExpressionVisitor
{
private RedundantConversionVisitor() { }
public static readonly RedundantConversionVisitor Default = new RedundantConversionVisitor();
protected override Expression VisitBinary(BinaryExpression node)
{
if(node.Type == typeof(bool) && node.Method == null
&& node.Left.NodeType == ExpressionType.Convert && node.Right.NodeType == ExpressionType.Convert
&& node.Left.Type == node.Right.Type)
{
UnaryExpression lhs = (UnaryExpression)node.Left, rhs = (UnaryExpression)node.Right;
if (lhs.Method == null && rhs.Method == null && lhs.Operand.Type == rhs.Operand.Type)
{
// work directly on the inner values
return Expression.MakeBinary(node.NodeType, lhs.Operand, rhs.Operand, node.IsLiftedToNull, node.Method);
}
}
return base.VisitBinary(node);
}
}
Output before:
(s, s1) => (Convert(s) == Convert(s1))
(s, s1) => (Convert(s) == Convert(s1))
Output after:
(s, s1) => (s == s1)
(s, s1) => (s == s1)