【发布时间】:2020-01-06 02:04:41
【问题描述】:
我有这种形状的功能,它可以进行一维寻根:
public delegate double Fun(double x, object o);
public static void Solve(Fun f, out double y, object o)
{
y = f(1.0, o); // all the irrelevant details of the algorithm omitted
}
这是一个固定的形状,以使算法可重用。考虑这是一个我无法更改的固定库函数(或者至少需要保持通用和可重用,并且不会针对这个问题的具体情况进行更改)。
我想传入一个函数,该函数需要在堆栈上保存Span<T>s 的外部参数以避免分配,但显然不能将Span<T>s 推入对象,因为这需要装箱和拆箱.
使用 lambda 表达式,调用代码可能类似于:
void CallingMethod()
{
Span<double> k1 = stackalloc double[n];
double answer;
Solve((x, o) => Wrapper(x, k1, o), out answer, null);
}
double Wrapper(double x, ReadOnlySpan<double> k1, object o)
{
return <some function of x and k1>;
}
但这不起作用,因为您无法使用 lambda 表达式在 Span<T>s 上形成闭包。它们也不能在泛型类型中使用,任何装箱和拆箱都不可用,不能作为 params 关键字传递,不能用于实例变量等。
有没有办法解决这个问题?
只是为了强调这个例子过于简化了。我可能有一个跨度,但我目前正在处理的问题需要通过 4 个跨度。我需要为任意数量的它们进行设计。
【问题讨论】:
-
记住
Span<T>代表堆栈上的内存 - 所以它不是关于装箱,而是更多地与 CLR 不能(还)保证 lambda 的闭包不会超过调用堆栈帧。 -
你不能用
Memory<T>吗? -
我使用
Span<T>来专门避免堆分配,Memory<T>在堆上 -
你能用
Memory<T>+ArrayPool<T>来避免新的分配吗? -
我认为您无法避免 lambda 发生内存分配。定义自己的
ValueType和Fun实现,来自己控制生命周期怎么样?
标签: c#