Каковы недостатки этого шаблона для обеспечения неизменности?
Учитывая следующий класс:
public static class ComboModel
{
public static Dictionary<int, int[]> Items()
{
return new Dictionary<int, int[]>
{
{
1,
new[] {
2,
3,
4
}
}
};
}
}
Я хочу обеспечить неизменность данных в классе, но это похоже на javascript-y и вызвало некоторую смутную (но сильную) критику со стороны моих сверстников. Что с этим не так?
1 ответ
Просто используйте ReadOnlyDictionary и выделите его только один раз:
public static class ComboModel {
private static readonly ReadOnlyDictionary<int, int[]> _items = new ReadOnlyDictionary<int, int[]>(new Dictionary<int, int[]> {
{
1,
new[] {
2,
3,
4
}
}
});
public static IReadOnlyDictionary<int, int[]> Items
{
get { return _items; }
}
}
Обратите внимание, что вы не только выделяете новый экземпляр для каждого вызова, как уже упоминалось ранее, - вы также даете неверное представление вызывающему абоненту, что он может изменить этот словарь. В ReadOnlyDictionary нет методов, которые могут его изменить. Есть и другие преимущества, когда вызывающий объект знает, что структура, которую он получил, не может быть изменена: например, он может безопасно обрабатывать элементы там с несколькими потоками.
Обновление: конечно, коллекции только для чтения волшебным образом не делают объекты, хранящиеся в этих коллекциях, доступными только для чтения - только сама коллекция. Если вы хотите обеспечить неизменность массивов int[] в вашем примере, просто сделайте их также только для чтения:
public static class ComboModel {
private static readonly IReadOnlyDictionary<int, ReadOnlyCollection<int>> _items = new ReadOnlyDictionary<int, ReadOnlyCollection<int>>(new Dictionary<int, ReadOnlyCollection<int>> {
{
1,
Array.AsReadOnly(new[] {
2,
3,
4
})
}
});
public static IReadOnlyDictionary<int, ReadOnlyCollection<int>> Items
{
get { return _items; }
}
}