remove safe dic
스터디/C++,CLI,C#2009. 12. 21. 14:24
작업하다보면 foreach 안에서 remove 를 할때가 꼭있다.
속도무시하고 편하게 사용하고 싶을때 사용하면 좋을듯하다.
어떤식으로 구현하는지 의도만 파악하고 자신의 입맛대로 바꾸길 바란다.
lib 코드
- using System;
using System.Collections;
using System.Collections.Generic;
using System.Text; - /// 버전 0.1
/// perpet@hitel.net 구본수
/// 소스 수정해서 사용하는건 문제 없으나 수정을 하면 반드시 원 제작자에게 수정된 소스를 메일로 보내야합니다. 버그나 개선된것을 꼭알려달라는 뜻입니다.
///
/// 초기 버전이라 버그가 많을수있습니다.. - namespace Foreach_safe_list
{ - class SafeCollection<TKey, TValue> //: Dictionary<TKey, TValue>
{
//원본리스트
Dictionary<TKey, TValue> _List = new Dictionary<TKey,TValue>(); - // 임시 add list
Dictionary<TKey, TValue> _AddList = new Dictionary<TKey, TValue>(); - // 임시 remove list
List<TKey> _RemoveList = new List<TKey>(); - public Dictionary<TKey, TValue>.KeyCollection Keys
{
get { return _List.Keys; }
- }
- public void Clear()
{
if (bForeachCount == 0)
{
_List.Clear();
}
else
{ - _AddList.Clear();
_RemoveList.Clear(); - foreach(TKey key in _List.Keys)
_RemoveList.Add(key); - }
- }
- public Dictionary<TKey, TValue>.ValueCollection Values {
get{return _List.Values;}
}
public bool ContainsKey(TKey key)
{
// 제일 먼저 add list 에서 찾아봐야한다
bool ret = _AddList.ContainsKey(key);
if (ret == true)
return true;
// 그다음 remove list 에서 찾아봐야한다.
if (_RemoveList.Contains(key))
{
return false;
}- return _List.ContainsKey(key);
} - public bool TryGetValue(TKey key, out TValue value)
{
if (bForeachCount == 0)
{
return _List.TryGetValue(key, out value);
}
else
{
// 제일 먼저 add list 에서 찾아봐야한다 - bool ret = _AddList.TryGetValue(key, out value);
if (ret == true)
return true; - // 그다음 remove list 에서 찾아봐야한다.
if (_RemoveList.Contains(key))
{
return false;
}
return _List.TryGetValue(key, out value);
}- //return false;
}
public void Add(TKey key ,TValue value)
{
if (bForeachCount == 0)
{
_List.Add(key, value);
}
else
{
_AddList.Add(key,value);
}- }
public void Remove(TKey key)
{
if (bForeachCount == 0)
{
_List.Remove(key);
}
else
{
if (_AddList.ContainsKey(key))
{
_AddList.Remove(key);
}
else
{
if (!_List.ContainsKey(key) || _RemoveList.Contains(key))
{
throw new Exception("dosen't have key");
}- _RemoveList.Add(key);
}
}
}
public void StartForeach()
{
bForeachCount++;
} - public void EndForeach()
{
bForeachCount--;
if (bForeachCount == 0)
{ - // remove 먼저해야함
- foreach (TKey item in _RemoveList)
{
_List.Remove(item);
} - _RemoveList.Clear();
- foreach (KeyValuePair<TKey, TValue> item in _AddList)
{
_List.Add(item.Key, item.Value);
}
_AddList.Clear();
}
}
public uint bForeachCount = 0;- public Dictionary<TKey, TValue>.Enumerator BaseGetEnumerator()
{
return _List.GetEnumerator();
} - public IEnumerator GetEnumerator()
{
return new SafeEnumerator(this);
}
class SafeEnumerator : IEnumerator, IDisposable
{
SafeCollection<TKey, TValue> _list;
Dictionary<TKey, TValue>.Enumerator enumerator;- public object Current { get { return enumerator.Current; } }
public bool MoveNext() { - while (enumerator.MoveNext())
{
if (_list._RemoveList.Contains(enumerator.Current.Key))
continue;
return true;
} - return false;
}
public void Reset() {
//enumerator...Reset();
} - public SafeEnumerator(SafeCollection<TKey, TValue> list)
{
_list = list;
enumerator = _list.BaseGetEnumerator(); - _list.StartForeach();
- }
- public void Dispose()
{
_list.EndForeach();
}
}
}
}
test code
- sdsd
- using System;
using System.Collections.Generic;
using System.Text; - namespace Foreach_safe_list
{ - class buff
{
public bool _flag;
public buff(bool flag)
{
_flag = flag;
}
public void update(){}
} - class Program
{ - static void Main(string[] args)
{
SafeCollection<int, buff> a = new SafeCollection<int, buff>(); - a.Add(1,new buff(true));
a.Add(2,new buff(true));
a.Add(3,new buff(false));
a.Add(4,new buff(true));
foreach (KeyValuePair<int, buff> aaa in a)
{
if( a.ContainsKey(2))
a.Remove(2);- foreach (KeyValuePair<int, buff> bbb in a)
{
bbb.Value.update();
if (bbb.Value._flag == false)
a.Remove(bbb.Key);
}
} - foreach (KeyValuePair<int, buff> aaa in a)
{
if (a.ContainsKey(2))
a.Remove(2); - foreach (KeyValuePair<int, buff> bbb in a)
{
if (!a.ContainsKey(2))
a.Add(2, new buff(true)); - }
- }
- foreach (KeyValuePair<int, buff> aaa in a)
{
Console.WriteLine("{0}", aaa.ToString());
} - }
}
}
이 글은 스프링노트에서 작성되었습니다.