我有一个创建 List<Action<int>>
的类并坚持到以后。此类可以在此列表中添加和删除委托(delegate)。只要人们不太花哨,这就很有效。为了对抗匿名函数(无法删除),我检查了委托(delegate)的目标是否为空。如果它为 null 我抛出异常。当有一个包含函数的匿名委托(delegate)时,问题就来了。这有一个目标,但同样不可移动。下面的简化代码说明了我的问题
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public void Add(Action<int> del)
{
if (del.Target == null)
{
throw new Exception("No static handlers");
}
m_Container.Add(del);
}
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
return false;
}
}
public class MyFakeActionClass
{
public void Test(int temp) { }
}
class Program
{
static void Main(string[] args)
{
bool removed = false;
int counter = 0;
MyDelegateContainer container = new MyDelegateContainer();
MyFakeActionClass fake = new MyFakeActionClass();
//container.Add(p => { }); //Throws, this is what I want to happen
container.Add(fake.Test); //Works, this is the use case
removed = container.Remove(fake.Test); //Works, this is the use case
Debug.Assert(removed);
container.Add(p => { fake.Test(p); counter++; }); //Works but I would like it not to
removed = container.Remove(p => { fake.Test(p); counter++; }); //doesn't work
Debug.Assert(removed);
}
}
我需要一些方法来识别
p => { fake.Test(p); counter++; }
是一个匿名函数,所以如果有人尝试我可以抛出它。感谢您的帮助
编辑:我应该注意到我可以使用 Action<int>
匿名函数的变量,一切都可以工作,但添加和删除在实践中永远不会在同一个范围内。
最佳答案
在您的示例中,调用者负责删除处理程序。因此,如果调用者不想删除处理程序,则无论处理程序是否为匿名委托(delegate)/lambda,它都不会被删除。
我的建议是将委托(delegate)容器更改为如下所示:
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public Action Add(Action<int> del)
{
m_Container.Add(del);
return new Action(() =>
{
m_Container.Remove(del);
});
}
}
调用者仍然负责删除处理程序,但不是再次将处理程序传递给容器,而是接收一个“ token ”,它可以保存并在以后用于删除处理程序。
关于c# - 如何识别匿名函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317769/