Я планирую использовать несколько названных словарей в проекте. Мой первый выбор состоял в том, чтобы использовать ключ string
, который является только свойством Name моих Value
элементов.Тип безопасности для ключей словаря?
Однако, это делает ключи словаря идентичны, даже если они доступ к различным типам:
private Dictionary<string, Foo> myFoos;
private Dictionary<string, Bar> myBars;
myFoos[bar.Name]; // shouldn't be able to do this!
Я хотел ключи быть типа несовместимы друг с другом, чтобы сделать их невозможно спутать друг с другом:
private Dictionary<FooName, Foo> myFoos;
private Dictionary<BarName, Bar> myBars;
Поскольку создание *Name
класса для каждого типа Value
является излишеством, я создал Name<T>
класс:
public struct Name<T>
{
public string Name;
// for convenience, could be explicit instead
static implicit operator string(Name<T> name)
{
return name.Name;
}
}
, который дал бы мне
private Dictionary<Name<Foo>, Foo> myFoos;
private Dictionary<Name<Bar>, Bar> myBars;
и тогда я мог бы хранить Name<Foo>
экземпляры вместо строк.
Это кажется немного громоздким, но это лучшее, что я придумал до сих пор - любые предложения о том, как это сделать лучше?
Является ли это ошибочным, или удивительным?
Проблема возникает, когда я хочу сохранить список баров, принадлежащих Foo. Вместо того, чтобы хранить вторую копию баров, я сохраняю Bar.Name - и словарь> начинает мутить воды. –
mskfisher
@mskfisher: это плохой подход. * Do * хранить бары напрямую, а не только их имена! Это * не * создание копий (если только ваши Foos и Bars не являются структурами, которых они не должны быть в этом случае). Если это классы, то их хранение не будет делать копии, оно просто будет хранить ссылки на объекты. Это фундаментальное свойство объектной ориентации, и ваш прецедент настолько распространен, что у него есть собственное имя: [агрегация] (http://en.wikipedia.org/wiki/Object_composition). –
@ Konrad: Хорошая добыча, и еще одна вещь, о которой я должен был упомянуть. Я собираюсь переходить между структурами и классами этого проекта, так как я хочу передавать копии между потоками по значению, а не по ссылке. Теперь я просматриваю только классы и создаю конструктор копирования для каждого типа, который мне нужно передать между потоками. – mskfisher