You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lambda表达式内部修改ref引用变量?

问题描述

我希望在Lambda表达式内部为ref引用变量赋值,以下是简化后的最小可复现示例(MRE):

public class Foo
{
    public int Value { get; private set; }
    public Foo(int value) => this.Value = value;
}

public class Test
{
    Foo F1 = new Foo(1);
    Foo F2 = new Foo(2);

    // 库方法,无法修改
    void LoadAsync(int value, Action<Foo> onSuccess)
    {
        // 这会在后续帧异步执行
        Foo f = new Foo(value);
        onSuccess(f);
    }

    // 我的方法,可以修改参数和实现,但不能改返回类型
    void LoadAndAssignAsync(int value, ref Foo fooToAssign)
    {
        LoadAsync(value, loadedFoo => fooToAssign = loadedFoo); // 此处不被允许

        // 因为加载是异步的,我不能在这里赋值`fooToAssign`,
        // 必须在Lambda内部完成赋值
    }

    void Start()
    {
        LoadAndAssignAsync(11, ref F1); // 希望保留这种简洁的调用方式
        LoadAndAssignAsync(24, ref F2);

       // 我想要一种简洁的写法:
       // 加载完成后,把结果赋值给我指定的变量(字段)
    }
}

Lambda无法捕获ref参数,当前写法不被允许。我希望找到简洁的替代方案,尽量保留ref F1这类简洁的调用方式,而非改用传递Lambda的繁琐写法。

注:此处的“异步”指Unity的协程机制,具体对应Addressables的AsyncOperationHandle操作。

解决方案

方案1:用包装类持有引用

创建简单的包装类来持有目标变量的引用,间接在Lambda中完成赋值,完全保留原有调用方式:

public class RefWrapper<T>
{
    public T Value { get; set; }
    public RefWrapper(ref T value) => Value = value;
}

// 修改你的方法实现
void LoadAndAssignAsync(int value, ref Foo fooToAssign)
{
    var wrapper = new RefWrapper<Foo>(ref fooToAssign);
    LoadAsync(value, loadedFoo => wrapper.Value = loadedFoo);
}

方案2:重载方法封装赋值逻辑

通过重载方法把ref参数转换为赋值委托,调用端写法不变,内部适配异步方法要求:

// 对外暴露的ref参数重载,保持调用简洁
void LoadAndAssignAsync(int value, ref Foo fooToAssign)
{
    LoadAndAssignAsync(value, f => fooToAssign = f);
}

// 内部实际调用的方法,接收赋值委托
void LoadAndAssignAsync(int value, Action<Foo> assignAction)
{
    LoadAsync(value, assignAction);
}

方案3:针对Unity场景的弱引用方案

如果是Unity类字段的场景,可以用弱引用避免额外类开销,注意仅适合字段(局部变量可能因生命周期回收失效):

void LoadAndAssignAsync(int value, ref Foo fooToAssign)
{
    var weakRef = new WeakReference<Foo>(fooToAssign);
    LoadAsync(value, loadedFoo =>
    {
        if (weakRef.TryGetTarget(out _))
        {
            fooToAssign = loadedFoo;
        }
    });
}

内容的提问来源于stack exchange,提问作者bolov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:05:24