目录
前言:
在开发过程中我们会遇到,使用字典dictionary时,可以在遍历(for或者foreach)时想删除的某一个符合条件的节点,普通的dictionary的无法能够提供支持。
一般情况下,我们往往需要定义一个字典dictionary 和一个List,来配合使用,比如:假定我一个玩家管理器需要管理很多玩家,在玩家的管理器的每帧调用的函数中需要遍历所有玩家,发现标记的IsDestroy的就删除该玩家
一、原始的代码实现
实现代码如下:
using System.Collections.Generic;
public class Player
{
//.............
//其他代码
//.............
private int _id;
private bool _destory;
public void SetDestory(bool destroy)
{
_destory = destroy;
}
public bool IsDestory()
{
return _destory;
}
/// <summary>
/// 每一帧都调用
/// </summary>
public void Update()
{
}
public int Id
{
get { return _id; }
set { _id = value; }
}
}
管理器代码:
public class PlayerManager
{
//管理玩家的Dictionary
private Dictionary<int, Player> _dict = new Dictionary<int, Player>();
//删除列表
private List<Player> _removeList = new List<Player>();
/// <summary>
/// 每一帧都调用
/// </summary>
public void Update()
{
foreach (var keyValuePair in _dict)
{
if (keyValuePair.Value.IsDestory())
{
_removeList.Add(keyValuePair.Value);
continue;
}
keyValuePair.Value.Update();
}
foreach (var player in _removeList)
{
_dict.Remove(player.Id);
}
}
}
以上代码能不能完成我们要的功能,答案时肯定的,但是不符合我的原则,做程序就要“偷懒”,所谓的懒人思想原则
二、可以遍历时删除字典设计
既然上面的的代码设计总体没有什么问题,那么我们对它进行封装,可以使用System.Collections.Generic命名空间中提供的Dictionary<TKey, TValue>类,并配合使用一个临时的List<TKey>对象来实现遍历时删除。
using System.Collections.Generic;
// 定义一个可以遍历时删除的字典类
public class RemoveableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
// 用于暂时存储需要删除的键
private List<TKey> removedKeys = new List<TKey>();
// 重写父类的Remove方法
public new void Remove(TKey key)
{
if (!removedKeys.Contains(key))
{
removedKeys.Add(key);
}
}
// 定义一个遍历时删除的方法,遍历结束后再删除指定的键
public void RemoveMarkedItems()
{
foreach (var key in removedKeys)
{
base.Remove(key);
}
removedKeys.Clear();
}
}
那么PlayerManager 代码该成如下代码:
public class PlayerManager
{
private RemoveableDictionary<int, Player> _dict = new RemoveableDictionary<int, Player>();
public void Update()
{
foreach (var keyValuePair in _dict)
{
if (keyValuePair.Value.IsDestory())
{
_dict.Remove(keyValuePair.Value.Id);
continue;
}
}
_dict.RemoveMarkedItems();
}
}
代码就简洁多了。
让然如果我们需要在 真正调用RemoveMarketItems删除的时候做点什么,比如调用删除destroy或清理clear函数,这应该无法拦住我们,这里给的只能思路而已,看到这里,不要忘记点赞收藏,谢谢。