考虑以下方法:
static void Invoke<TArg>(Action<TArg> action, TArg arg) => action(arg);
我知道; 它看起来没什么用,但它是实际代码的简化。
无论如何,我需要Invoke
从具有按引用参数的方法进行调用,并传递 lambda action
。我需要某种方法从 lambda 内部返回按引用参数的值。最后,lambda 必须是static
(非捕获)。
我想出了以下古怪的方案:
static unsafe void UpdateFooAndGetBar(ref object foo, out object bar) {
var args = (foo, bar: (object)null);
Invoke(
static pArgs => {
ref var args = ref Unsafe.AsRef<(object, object)>(pArgs.ToPointer());
args.Item1 = 123;
args.Item2 = "baz";
},
new IntPtr(Unsafe.AsPointer(ref args))
);
foo = args.foo;
bar = args.bar;
}
这似乎有效,但Unsafe
让我紧张。那么,我的代码合法吗?有没有更好的办法?
假设我们有一个允许by-ref 使用的自定义委托:
然后我们可以在我们的
Invoke
:并在没有任何非托管指针的情况下使用它:
您还可以更进一步,拥有一个符合您确切需求的自定义委托,但可重用性较差: