Универсальная Карта Идентификационных данных в C#. Не хочу общедоступного конструктора

Если Ваш идентификатор является возрастающим, затем используют что-то как

delete from table where id < (select max(id) from table)-N
5
задан Lobstrosity 10 September 2009 в 15:49
поделиться

2 ответа

Вместо требования ограничения конструктора передайте 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 более эффективный, кстати.)

9
ответ дан 13 December 2019 в 19:31
поделиться

Благодаря Джону, вот рабочий код:

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));
}
2
ответ дан 13 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: