这是 C# 中丢失的引用吗?

本文关键字:引用 这是 | 更新日期: 2023-09-27 18:32:15

我有一些这样的代码:

public delegate void InputEventListener<T>(T e) where T : InputEvent;
private Dictionary<System.Type, System.Delegate> processors = new Dictionary<System.Type,System.Delegate>();
public bool RegisteEventListener<T>(InputEventListener<T> listener) where T : InputEvent
{
        System.Type tt = typeof(T);
        if(!processors.ContainsKey(tt))
        {
            InputEventListener<T> lis = new InputEventListener<T>(listener);
            processors.Add(tt, lis);
            return true;
        }
        InputEventListener<T> aaa = processors[tt] as InputEventListener<T>;
        aaa += (listener);
        //key point
        processors[tt] = aaa;   
        return true;
}

当我尝试将第二个侦听器添加到具有相同类型的处理器中时,如果我不调用以下关键点行:

processors[tt] = aaa;

字典不会存储侦听器。 但是委托应该是引用类型吧? 当我修改 AAA 时,它应该直接更改字典中的数据,但为什么我仍然需要这行代码来使其工作?

这是 C# 中丢失的引用吗?

委托类型是引用类型,是的。但就像System.String一样,它们是不可变的。当您编写的代码看起来好像在修改实例时,您实际上是在创建新值的新实例。

因此,如果您的字典中有一个委托实例,然后编写类似 aaa += (listener); 的内容,您将创建一个全新的委托实例并将其分配给变量 aaa 。原始委托实例保留在字典中(或任何地方...在何处引用原始委托实例并不重要,它始终保持不变)。

以下是其他几个相关的答案:

为什么 .net 委托分配运算符未将引用分配给原始委托?
如果委托是不可变的,为什么我可以做像 x += y 这样的事情?