闭包分配和引用传递
本文关键字:引用 分配 闭包 | 更新日期: 2023-09-27 18:34:05
我有一个函数,看起来像:
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 索引参数中,它显示
闭包分配:"索引"、"通道"参数和"this"引用
据我了解,传递 int ref 不应该创建新副本!有谁知道为什么会发生这种情况,我能做些什么来避免它?
提前非常感谢
由此
private void OnItemChannelsListChanged(object sender, ListChangedEventArgs args)
我认为您正在触发一个事件,您没有像您在第一行中所说的那样"具有功能"。
如果您从事件处理程序外部调用 UpdateLogsNewAssignedUnit 函数,我敢打赌分配不会发生。事件通常作为多播委托实现(它们不必是,但通常是(。由于是从事件处理程序调用它,因此编译器正在创建一个要在调用中使用的状态对象。有关详细信息,请参阅此文章。具体说来:
在引入 lambdas/anonymous 方法之前,想要调用接受委托的方法的 C# 开发人员通常需要定义一个类来存储其状态,向该类添加一个方法以执行其处理,然后在该状态实例上创建一个指向该方法的委托,例如
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);
}
}
现在在 C# 中,当您使用匿名方法或 lambda 时,编译器实际上最终会代表您生成与此几乎相同的代码,因此您不再需要手动执行此操作。 下面是为我之前使用匿名方法的示例生成的内容的反编译版本:
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);
}
}