69 lines
2.3 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|