c# - 闭包分配和引用传递

标签 c# closures

我有一个如下所示的函数:

private void OnItemChannelsListChanged(object sender, ListChangedEventArgs args)
{
...
int index = args.NewIndex;
this.UpdateLogsOnNewAssignedUnit(ref index, channels);
}

哪里

private void UpdateLogsNewAssignedUnit(ref int index, List<IChannel> channels)
{
}

我使用一个名为“堆分配查看器插件”的插件(ps。我不隶属于他们),它可以在编辑器上直观地显示堆分配。好吧,在它下面的 ref int index 参数中显示

Closure allocation: 'index', 'channels' parameters and 'this' reference

根据我的理解,传递 int ref 不应创建新副本! 有谁知道为什么会发生这种情况以及我该怎么做才能避免它?

提前非常感谢

最佳答案

从此

private void OnItemChannelsListChanged(object sender, ListChangedEventArgs args)

我认为您正在触发一个事件,您没有像您在第一行中所说的“有功能”。

如果您从事件处理程序外部调用 UpdateLogsNewAssignedUnit 函数,我敢打赌分配不会发生。事件通常被实现为多播委托(delegate)(它们不是必须的,但通常是)。由于您是从事件处理程序调用它,因此编译器将创建一个状态对象以在调用中使用。请参阅this文章了解更多信息。具体来说:

Before lambdas/anonymous methods were introduced, C# developers wanting to call a method that accepted a delegate would typically need to define a class to store their state, add a method to that class to do their processing, and then create a delegate that pointed to that method on that state instance, e.g.

    public static void WriteOnPool(Stream stream, byte [] data) 
    { 
        var state = new WriteOnPoolState(); 
        state.stream = stream; 
        state.data = data; 
        ThreadPool.QueueUserWorkItem(new WaitCallback(state.Invoke)); 
    } 

    private sealed class WriteOnPoolState 
    { 
        public Stream stream; 
        public byte [] data; 

        public void Invoke(object ignored) 
        { 
            stream.Write(data, 0, data.Length); 
        }    
    }

Now in C#, when you use an anonymous method or lambda, the compiler actually ends up generating code almost identical to this on your behalf so that you no longer have to do so manually. Here’s a decompiled version of what gets generated for my previous example that used an anonymous method:

    public static void WriteOnPool(Stream stream, byte[] data) 
    { 
        var locals2 = new DisplayClass1(); 
        locals2.stream = stream; 
        locals2.data = data; 
        ThreadPool.QueueUserWorkItem( 
            new WaitCallback(locals2.<WriteOnPool>b__0)); 
    } 

    [CompilerGenerated] 
    private sealed class DisplayClass1 
    { 
        public Stream stream; 
        public byte[] data; 

        public void <WriteOnPool>b__0(object param0) 
        { 
            this.stream.Write(this.data, 0, this.data.Length); 
        } 
    }

关于c# - 闭包分配和引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425662/

相关文章:

javascript - 对象函数 () { } 没有方法 'my method'

javascript - JS 关闭的问题

c# - 无法迭代 int 的位表示

c# - 使用 log4net 的日志程序集版本?

c# - 尝试使用带有 c# 的 xamarin android 打开默认浏览器

javascript - 在子函数中访问循环迭代?

javascript - 我真的不知道javascript闭包

c# - 是否可以为 Func<T1,T2,....> 参数的部分提供智能感知的 xml 注释?

c# - 字典键和值是否以相同顺序枚举?

ios - 上下文闭包类型 '(Data?, URLResponse?, Error?) -> Void' 需要 3 个参数,但闭包主体中使用了 1 个参数