Реализация свойства Tag в классах сущностей

Когда я создаю сущности в библиотеке классов, я склоняюсь к добавлению свойства Tag , которое может использоваться пользователями и расширением библиотек для хранения произвольных данных. с объектом. Теперь я ищу лучший способ реализации такого свойства Tag в моей библиотеке классов и причины, по которым это происходит.

В System.Windows.Forms Microsoft использует object Tag {get; набор; } в качестве подписи, но это выглядит слишком ограниченно, поскольку только один может использовать тег в любое время.

Я также подумал о HashTable Tag {get; } , чтобы позволить кому-либо устанавливать и получать любые данные по ключу, но это кажется слишком «разоблачающим» для библиотеки классов. Тогда IDictionary Tag {get; } будет лучшим вариантом, но оба позволят любому очистить весь словарь, которого я хочу избежать. Опять же, и HashTable, и IDictionary позволяют работать только с экземплярами объекта , где что-то общее может быть лучшим выбором. Но Словарь Tag {get; } , очевидно, не будет работать для всех возможных потребителей.

Итак, какой путь?

Редактировать: и HashTable, и IDictionary позволяют работать только с экземплярами объекта , где что-то общее может быть лучшим выбором. Но Словарь Tag {get; } , очевидно, не будет работать для всех возможных потребителей.

Итак, какой путь?

Редактировать: и HashTable, и IDictionary позволяют работать только с экземплярами объекта , где что-то общее может быть лучшим выбором. Но Словарь Tag {get; } , очевидно, не будет работать для всех возможных потребителей.

Итак, какой путь?

Редактировать: Как правильно подсказал Тимви ниже, я не хочу, чтобы разные пользовательские классы могли мешать друг другу. Я предполагаю сценарий, в котором есть много классов сущностей и только несколько классов, которые хотят хранить связанные данные.

1
задан Daniel A.A. Pelsmaeker 24 August 2010 в 12:38
поделиться

3 ответа

Похоже, что одно из ваших требований состоит в том, чтобы отдельные потоки или процессы, которые обращаются к объекту сущности, не могли видеть личные данные друг друга. Боюсь, это довольно хороший показатель того, что личные данные не должны находиться в объекте сущности, которым они пользуются. Вместо этого у каждого процесса должны быть свои личные данные.Он не обязательно должен быть в самим объектом сущности, но он может быть связан с объектом сущности через частный словарь:

private Dictionary<Entity, object> myPrivateEntityData = new ...;

Кроме того, поскольку теперь он является частным для процесса, и процесс предположительно точно знает, какие данные он хочет связать с каждой сущностью, теперь вы можете сделать его полностью безопасным для типов.

private Dictionary<Entity, SuperSecretSpecialData> myPrivateEntityData = new ...;

private sealed class SuperSecretData {
    public bool     NoOne;
    public int      ElseBut;
    public string   MeCan;
    public DateTime SeeThis;
}

Есть некоторая боль, связанная с необходимостью сначала проверять, есть ли каждая сущность в словаре, но вы тоже можете это исправить. Лично я использую класс AutoDictionary , который просто расширяет Dictionary таким образом, что он автоматически создает объекты, когда они отсутствуют:

public sealed class AutoDictionary<TKey, TVal> : Dictionary<TKey, TVal> where TVal : class, new()
{
    public new TVal this[TKey key]
    {
        get
        {
            if (!ContainsKey(key))
                Add(key, new TVal());
            return base[key];
        }
        set
        {
            base[key] = value;
        }
    }
}

private AutoDictionary<Entity, SuperSecretSpecialData> myPrivateEntityData = new ...;

Тогда вы можете легко получить доступ к myPrivateEntityData [someEntity ] .NoOne (и т. Д.), И он будет просто работать и никогда не будет генерировать исключение, потому что ключа нет, и тем не менее вы все равно можете использовать ContainsKey , если вы хотите , чтобы проверьте, есть ли оно там.

1
ответ дан 2 September 2019 в 21:54
поделиться

Может быть, что-то вроде этого?


public class Taggable :ITaggable
    {
        private IDictionary<string, object> _tags = new Dictionary<string, object>();
        public void AddTag(string key, object tag)
        {
            _tags.Add(key,tag);
        }

        public bool IsTag(string key)
        {
            return _tags.ContainsKey(key);
        }

        public T GetTag<T>(string key)
        {
            return (T) _tags[key];
        }
        public void RemoveTag(string key)
        {
            _tags.Remove(key);
        }
    }

Хотя я не включил это, все четыре метода есть в интерфейсе.

Никто не может «злоупотреблять» коллекцией, так как ему нужно знать ключ.

1
ответ дан 2 September 2019 в 21:54
поделиться

Вы можете расширить IDictionary или Dictionary , чтобы сделать его изменяемым. Однако что-то мне подсказывает, что вы, вероятно, в целом ошибаетесь. Коллекции с произвольной типизацией всегда доставляют удовольствие при доставке ...

Это просто мой 2c, вроде субъективно, но я избегаю свободных типов, если они не нужны.

0
ответ дан 2 September 2019 в 21:54
поделиться
Другие вопросы по тегам:

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