C# HashSet, но вы хотите вызвать исключение при добавлении дубликатов

Я хочу использовать HashSet, но беспокоюсь, что он «тихо» поглощает дубликаты (возвращая true/false), но не выдавая исключение. Меня интересует эквивалентная структура данных, которая выдает исключение (например, словарь).

Какой лучший подход для этого?

Используйте Dictionary?

Heretic Monkey 09.08.2024 18:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете просто определить метод расширения на HashSet<T> (и доверять ему немного больше, чтобы не пришлось этого делать).

public static class Extensions {
    public static void AddWithThrow<T>(this HashSet<T> hashSet, T value) {
        if (hashSet.Add(value) == false) {
            throw new ArgumentException("An item with the same value has already been added");
        }
    }
}

и если по какой-то причине у вас был приемный метод ICollection<T>, который хочет добавить семантику Add, возможно, это:

public class ThrowingHashSet<T> : HashSet<T>, ICollection<T> {

    // uncomment if you can live with the confusion
    // of HashSet<T> variables and HashSet<T> accepting methods
    // calling the existing HashSet<T>.Add non-throwing method instead

    // public new void Add(T value) => AddWithThrow(value);

    private void AddWithThrow(T value) {
        if (base.Add(value) == false) {
            throw new ArgumentException("An item with the same value has already been added");
        }
    }
    void ICollection<T>.Add(T item) => this.AddWithThrow(item);
}

Будьте осторожны: этот трюк не работает, если тип переменной — HashSet<T>. Затем вызывается исходный (и до сих пор существующий) метод Add().

Progman 09.08.2024 22:40

@Progman Я прямо сказал об этом при использовании ссылкиICollection<T>... во втором предлагаемом решении...

Ivan Petrov 09.08.2024 23:39

все еще отредактировал ответ, который добавляет предупреждение.

Ivan Petrov 09.08.2024 23:52

Другие вопросы по теме