Реализация свойства Tag на классах сущностей - PullRequest
1 голос
/ 24 августа 2010

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

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

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

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

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

Ответы [ 3 ]

1 голос
/ 24 августа 2010

Что-то вроде этого может быть?


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 голос
/ 24 августа 2010

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

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, если вы хотите , чтобы проверить, существует ли он.

0 голосов
/ 24 августа 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...