这个面试题的代码有什么问题?
What are the problems with the code in this interview question?
我最近不得不回答一些求职面试的编码练习,但下面的一个让我难住了。我认为该代码应该是移动应用程序使用的 Web 服务的一部分。
问:下面的代码有哪些潜在问题?你会如何解决它?
public class Service
{
public event EventHandler<EventArgs> ItemCreated;
private Dictionary<Guid, Listener> _listeners = new Dictionary<Guid, Listener>();
public Guid Login()
{
var listener = new Listener(this);
var token = Guid.NewGuid();
_listeners[token] = listener;
return token;
}
public void Logout(Guid token)
{
_listeners.Remove(token);
}
}
public class Listener
{
public Listener(Service service)
{
service.ItemCreated += OnItemCreated;
}
private void OnItemCreated(object sender, EventArgs e)
{ }
}
我已经把代码放到一个项目中,它运行没有任何问题。
到目前为止我最好的结果是似乎没有任何地方触发事件,但是因为代码没有任何进一步的解释可以修复我怀疑我是否正确
更新
感谢您的回答。我已经更新了我建议的修复。
public void Logout(Guid token)
{
_listeners[token].Unsubscribe(this);
_listeners.Remove(token);
}
public class Listener
{
...
public void Unsubscribe(Service service)
{
service.ItemCreated -= OnItemCreated;
}
}
我认为,面试官正在解决的这段代码的主要问题是,在 Logout
上,侦听器已从 _listeners
字典中删除,但并未从 service.ItemCreated
事件中取消订阅,这将导致 memory leak, cause GC will not be able to collect it (cause event will hold the reference to listener). Also, as @Klaus Gütter 在对我的回答的评论中陈述,它可能会导致 security/business 应用程序中的逻辑问题,具体取决于实际上下文。
我最近不得不回答一些求职面试的编码练习,但下面的一个让我难住了。我认为该代码应该是移动应用程序使用的 Web 服务的一部分。
问:下面的代码有哪些潜在问题?你会如何解决它?
public class Service
{
public event EventHandler<EventArgs> ItemCreated;
private Dictionary<Guid, Listener> _listeners = new Dictionary<Guid, Listener>();
public Guid Login()
{
var listener = new Listener(this);
var token = Guid.NewGuid();
_listeners[token] = listener;
return token;
}
public void Logout(Guid token)
{
_listeners.Remove(token);
}
}
public class Listener
{
public Listener(Service service)
{
service.ItemCreated += OnItemCreated;
}
private void OnItemCreated(object sender, EventArgs e)
{ }
}
我已经把代码放到一个项目中,它运行没有任何问题。
到目前为止我最好的结果是似乎没有任何地方触发事件,但是因为代码没有任何进一步的解释可以修复我怀疑我是否正确
更新
感谢您的回答。我已经更新了我建议的修复。
public void Logout(Guid token)
{
_listeners[token].Unsubscribe(this);
_listeners.Remove(token);
}
public class Listener
{
...
public void Unsubscribe(Service service)
{
service.ItemCreated -= OnItemCreated;
}
}
我认为,面试官正在解决的这段代码的主要问题是,在 Logout
上,侦听器已从 _listeners
字典中删除,但并未从 service.ItemCreated
事件中取消订阅,这将导致 memory leak, cause GC will not be able to collect it (cause event will hold the reference to listener). Also, as @Klaus Gütter 在对我的回答的评论中陈述,它可能会导致 security/business 应用程序中的逻辑问题,具体取决于实际上下文。