如何从Span T获得价值?与Linq表达树? [英] How to get a value out of a Span<T> with Linq expression trees?

查看:57
本文介绍了如何从Span T获得价值?与Linq表达树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Linq表达式树来调用Span<T>的索引器.代码如下:

I would like to use Linq expression trees to call the indexer of a Span<T>. The code looks like:

var spanGetter = typeof(Span<>)
    .MakeGenericType(typeof(float)).GetMethod("get_Item");

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

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

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

但是,此代码失败,因为myValue的类型是Single&(又名ref struct),而不是类型Single(又名struct).

Yet, this code fails because myValue is of type Single& (aka ref struct) instead of type Single (aka struct).

如何从表达式树中评估Span<T>?

How to evaluate a Span<T> from an expression tree?

推荐答案

我有一个解决方案,但是正如您所看到的,它远非理想.我们重新使用C#语法糖引擎.

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);
}

这篇关于如何从Span T获得价值?与Linq表达树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆