Это в порядке для использования интервала для ключа в KeyedCollection

Мое предложение:


Регулярные выражения:

  • \ s символ пробела.

  • + означает одно или несколько вхождений.

PHP (из http://php.net ):

blockquote>

11
задан Jon B 14 October 2008 в 16:49
поделиться

4 ответа

В основном необходимо решить, будут ли пользователи класса, вероятно, смущены тем, что они не могут, например, сделать:

for(int i=0; i=< myCollection.Count; i++)
{
    ... myCollection[i] ...
}

хотя они могут, конечно, использовать foreach или использовать бросок:

for(int i=0; i=< myCollection.Count; i++)
{
    ... ((Collection<MyType>)myCollection)[i] ...
}

Это не легкое решение, поскольку это может легко привести к heisenbugs. Я решил позволить его в одном из моих приложений, где доступ от пользователей класса был почти исключительно ключом.

Я не уверен, что сделал бы так для общей библиотеки классов хотя: в целом я постарался бы не подвергать KeyedCollection в общедоступном API: вместо этого я выставил бы IList <T> в общедоступном API, и потребители API, которым нужен доступ по ключу, могут определить свой собственный внутренний KeyedCollection с конструктором, который берет IEnumerable <TItem> и заполняет набор с ним. Это означает, что можно легко создать новый KeyedCollection из списка, полученного от API.

Относительно сериализации существует также проблема производительности, о которой я сообщил к Microsoft Connect: KeyedCollection поддерживает внутренний словарь, а также список, и сериализирует обоих - достаточно сериализировать список, поскольку словарь может легко быть воссоздан на десериализации.

Поэтому, а также ошибка XmlSerialization, я рекомендовал бы постараться не сериализировать KeyedCollection - вместо этого, только сериализируют KeyedCollection. Список объектов.

Мне не нравится предложение обертывания Вашего международного ключа в другом типе. Это, кажется, мне неправильно добавляет сложность просто так, чтобы тип мог использоваться в качестве объекта в KeyedCollection. Я использовал бы строковый ключ (ToString) вместо того, чтобы делать это - это скорее похоже на класс Набора VB6.

FWIW, я задал тот же вопрос некоторое время назад на форумах MSDN. Существует ответ от члена команды FxCop, но никакие окончательные инструкции.

7
ответ дан 3 December 2019 в 08:57
поделиться

Могло бы быть лучше добавить a GetById(int) метод к типу набора. Collection<T> может использоваться вместо этого, если Вам не нужен никакой другой ключ для доступа к содержащим в нем объектам:

public class FooCollection : Collection<Foo>
 { Dictionary<int,Foo> dict = new Dictionary<int,Foo>();

   public Foo GetById(int id) { return dict[id]; }

   public bool Contains(int id) { return  dict.Containskey(id);}

   protected override void InsertItem(Foo f)
    { dict[f.Id] = f;
      base.InsertItem(f);
    }

   protected override void ClearItems()
    { dict.Clear();
      base.ClearItems();
    }

   protected override void RemoveItem(int index)
    { dict.Remove(base.Items[index].Id);
      base.RemoveItem(index);
    }

   protected override void SetItem(int index, Foo item)
    { dict.Remove(base.Items[index].Id);
      dict[item.Id] = item;
      base.SetItem(index, item);
    }
 }









 }
2
ответ дан 3 December 2019 в 08:57
поделиться

Ключ в KeyedCollection должен быть уникальным и быстро получаемым от собираемого объекта. Учитывая класс человека, например, это могло быть свойство SSN или возможно даже конкатенирующие свойства FirstName и LastName (если результат, как известно, уникален). Если идентификатор является законно полем объекта, собираемого, чем это - допустимый кандидат на ключ. Но, возможно, попытайтесь снять его в качестве строки вместо этого для предотвращения коллизии.

1
ответ дан 3 December 2019 в 08:57
поделиться

Легкое решение могло бы состоять в том, чтобы перенестись int в другой тип для создания отличного типа для разрешения перегрузки. Если Вы используете a struct, эта обертка не имеет никаких дополнительных издержек:

struct Id {
    public int Value;

    public Id(int value) { Value = value; }

    override int GetHashCode() { return Value.GetHashCode(); }

    // … Equals method.
}
3
ответ дан 3 December 2019 в 08:57
поделиться
Другие вопросы по тегам:

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