ln.collections/ln.collections/ObjectIdentityCache.cs

69 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace ln.collections
{
public class ObjectIdentityCache
{
Dictionary<object, object> objectsByIdentity = new Dictionary<object, object>();
Dictionary<object, object> identitiesByObject = new Dictionary<object, object>();
Func<object, object> IdGetter;
public ObjectIdentityCache(Func<object,object> idGetter)
{
if (idGetter == null)
throw new ArgumentNullException(nameof(idGetter));
IdGetter = idGetter;
}
public object this[object identity] => objectsByIdentity[identity];
public void Update(object o)
{
if (identitiesByObject.TryGetValue(o, out object knownObject) && (!object.Equals(o, knownObject)))
throw new ArgumentException("another instance already known with this identity", nameof(o));
if (!object.ReferenceEquals(null, knownObject))
{
object knownIdentity = identitiesByObject[knownObject];
object objectIdentity = IdGetter(knownObject);
if (!object.Equals(knownIdentity, objectIdentity))
{
objectsByIdentity.Remove(knownIdentity);
objectsByIdentity.Add(knownIdentity, knownObject);
identitiesByObject[knownObject] = objectIdentity;
}
} else
{
object objectIdentity = IdGetter(o);
objectsByIdentity.Add(objectIdentity, o);
identitiesByObject.Add(o, objectIdentity);
}
}
public void RemoveObject(object o)
{
if (identitiesByObject.TryGetValue(o, out object objectIdentity))
{
identitiesByObject.Remove(o);
objectsByIdentity.Remove(objectIdentity);
}
}
public void RemoveIdentity(object objectIdentity)
{
if (objectsByIdentity.TryGetValue(objectIdentity, out object o))
{
objectsByIdentity.Remove(objectIdentity);
identitiesByObject.Remove(o);
}
}
}
}