Cosmos/source2/IL2CPU/Cosmos.IL2CPU/OurHashSet.cs
2010-09-07 20:11:56 +00:00

82 lines
No EOL
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Cosmos.IL2CPU
{
// Contains known types and methods, both scanned and unscanned
// We need both a HashSet and a List. HashSet for speed of checking
// to see if we already have it. And mItems contains an indexed list
// so we can scan it as it changes. Foreach can work on HashSet,
// but if foreach is used while its changed, a collection changed
// exception will occur and copy on demand for each loop has too
// much overhead.
// we use a custom comparer, because the default Hashcode does not work.
// In .NET 4.0 has the DeclaringType often changed to System.Object,
// didn't sure if hashcode changed. The situation now in .NET 4.0
// is that the Contains method in OurHashSet checked only the
// default Hashcode. With adding DeclaringType in the Hashcode it runs.
public class OurHashSet<T> : IEnumerable<T>
{
private Dictionary<int, T> mItems = new Dictionary<int, T>();
public bool Contains(T aItem)
{
if (aItem == null)
throw new ArgumentNullException("aItem");
return mItems.ContainsKey(GetHash(aItem));
}
public void Add(T aItem)
{
if (aItem == null)
throw new ArgumentNullException("aItem");
mItems.Add(GetHash(aItem), aItem);
}
public IEnumerator<T> GetEnumerator()
{
return (from item in mItems
select item.Value).GetEnumerator();
}
public T GetItemInList(T aItem)
{
if (aItem == null)
throw new ArgumentNullException("aItem");
T xResult;
if (mItems.TryGetValue(GetHash(aItem), out xResult))
return xResult;
else
return aItem;
}
IEnumerator IEnumerable.GetEnumerator()
{
return (from item in mItems
select item.Value).GetEnumerator();
}
public static Type GetDeclareType(T item)
{
var xMethodDeclaringType = item.GetType().GetMethod("get_DeclaringType");
var xDeclaringType = xMethodDeclaringType.Invoke(item, null) as Type;
return xDeclaringType;
}
public static string GetDeclareTypeString(T item)
{
var xName = GetDeclareType(item);
return xName == null ? string.Empty : xName.ToString();
}
public static int GetHash(T item)
{
return (item.ToString() + GetDeclareTypeString(item)).GetHashCode();
}
}
}