Если Ваш идентификатор является возрастающим, затем используют что-то как
delete from table where id < (select max(id) from table)-N
Вместо требования ограничения конструктора передайте Func
конструктору карты. Таким образом, конструктор может быть внутренним, но карта все еще может эффективно вызывать его:
public class EntityMap<T> where T : Entity
{
private readonly Dictionary<int, T> _entities = new Dictionary<int, T>();
private readonly object _getLock = new object();
private readonly Func<T> _entityGenerator;
public T Get(int id)
{
lock (_getLock)
{
T ret;
if (!_entities.TryGetValue(id, ret))
{
ret = entityGenerator();
newEntity[id] = ret;
ret.Id = id;
}
return ret;
}
}
internal EntityMap(Func<T> entityGenerator)
{
_entityGenerator = entityGenerator;
}
}
Затем инициализируйте его с помощью:
EntityMap<Widget> widgetMap = new EntityMap(() => new Widget());
Вы можете потенциально сделать его Func
вместо этого и сделать делегат, ответственный за создание объекта с правильным идентификатором. Таким образом вы сможете сделать свой идентификатор доступным только для чтения, используя его в качестве параметра конструктора Entity
.
(Я взял на себя смелость сделать ваш метод Get
более эффективный, кстати.)
Благодаря Джону, вот рабочий код:
public abstract class Entity
{
private readonly int _id;
public int Id
{
get { return _id; }
}
internal Entity(int id)
{
_id = id;
}
}
public sealed class Widget : Entity
{
internal Widget(int id) : base(id) { }
}
public sealed class Gadget : Entity
{
internal Gadget(int id) : base(id) { }
}
public class EntityMap<T> where T : Entity
{
private readonly Dictionary<int, T> _entities = new Dictionary<int, T>();
private readonly object _getLock = new object();
private readonly Func<int, T> _entityGenerator;
public T Get(int id)
{
lock (_getLock)
{
T entity;
if (!_entities.TryGetValue(id, out entity))
_entities[id] = entity = _entityGenerator(id);
return entity;
}
}
internal EntityMap(Func<int, T> entityGenerator)
{
_entityGenerator = entityGenerator;
}
}
public static class ApplicationMap
{
public static readonly EntityMap<Widget> Widgets = new EntityMap<Widget>(id => new Widget(id));
public static readonly EntityMap<Gadget> Gadgets = new EntityMap<Gadget>(id => new Gadget(id));
}