我想使用 Linq 表达式树来调用 a 的索引器Span<T>
。代码如下:
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&
(aka ref struct
) 而不是类型Single
(aka struct
).
如何评价一个Span<T>
来自表达式树?
我有一个解决方案,但它远非理想,正如您将看到的。我们重新使用 C# 语法糖引擎。
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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)