Arithmetic on 'Single&' with Linq expression trees?

c# expression-trees linq

Question

In C#, I would like to construct an arithmetic expression with the Linq expression trees when working with float obtained from a Span<float> Attempting to use Expression.Multiply fails with InvalidOperationException thrown with The binary operator Multiply is not defined for the types 'System.Single&' and 'System.Single&'.

The sub-expressions are Single& instead of Single value and produced with:

var val = Expression.Call(
   mySpan,
   typeof(Span<>).MakeGenericType(typeof(float).GetMethod("get_Item"),
   myIndex)

Do do I convert Single& to Single? or alternatively, is there a more idiomatic way to call the indexer of a Span<float>?

1
1
8/30/2018 9:03:48 PM

Accepted Answer

I have a solution, but it's far from being ideal, as you'll see. We re-use C# syntactic sugar engine.

class Program
{
    static void Main(string[] args)
    {
        var spanGetter = typeof(Program).GetMethod("GetItem").MakeGenericMethod(typeof(float));

        var myFloatSpan = Expression.Parameter(typeof(Span<float>), "s");

        var myValue = Expression.Call(
            null,
            spanGetter,
            myFloatSpan,
            Expression.Constant(42));

        var myAdd = Expression.Add(
            myValue,
            Expression.Constant(13f));

        var expr = Expression.Lambda<MyFunc>(myAdd, myFloatSpan).Compile();

        var span = new Span<float>(new float[43]);
        span[42] = 12.3456f;
        Console.WriteLine(expr(span)); // -> 25.3456
    }

    // hopefully, this shouldn't be too bad in terms of performance...
    // C# knows how to do compile this, while Linq Expressions doesn't
    public static T GetItem<T>(Span<T> span, int index) => span[index];

    // we need that because we can't use a Span<T> directly with Func<T>
    // we could make it generic also I guess
    public delegate float MyFunc(Span<float> span);
}
7
9/5/2018 8:06:50 AM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow