Я конкретно думаю о наборе, который выполняет контракт набора, но я думаю, что вопрос может относиться к любому виду. Есть ли наборы в платформе.NET, которые предотвращают пустые записи? Определенное поведение, которое я хочу, является этим:
var set = new HashSet<object>();
bool added = set.Add(null);
Console.WriteLine(added); // prints "False"
Это не поведение встроенного HashSet<T>
. Есть ли какие-либо наборы, которые действительно имеют это (или подобный) поведением, или действительно ли я - более обеспеченная прокрутка мое собственное? Если последний, что лучший способ состоит в том, чтобы пойти об этом? Если я наследовался непосредственно HashSet<T>
или просто оберните его?
Править: Чтобы быть ясным, это - просто неактивное удивление. Главным образом, потому что я не могу думать ни о какой причине, я когда-либо хотел бы позволить null
в ряд объектов. У меня нет никакой конкретной потребности в этом.
Нет такого встроенного класса, как HashSet
, за исключением этого единственного поведения.
Если вам это нужно, я бы порекомендовал сделать свой собственный. Однако я не рекомендую создавать подклассы HashSet
. Ни один из методов (например, Add
, который вы явно хотите изменить) не является виртуальным, поскольку на самом деле он не был разработан с учетом создания подклассов. Это вызовет странное поведение при использовании, поскольку вы скроете унаследованные методы.
Просто инкапсулируйте HashSet
и предоставьте необходимые вам элементы. Единственный реальный «код», который вам нужно добавить, - это одна проверка на null для метода Add - в противном случае просто передайте все методы инкапсулированному экземпляру.
Если вы хотите, чтобы это был общий класс, вам нужно добавить дополнительное ограничение для работы только с классами, поскольку вы хотите иметь нулевую проверку:
public class ValueSet<T> : ICollection<T>, IEnumerable<T>, ICollection
where T : class
{
private HashSet<T> hashSet = new HashSet<T>();
// ... Implement all members as needed...
А как насчет написания метода расширения для HashSet. Это может быть проще всего.
public static class HashSetExtensions
{
public static bool AddNonNull<T>(this HashSet<T> set, T item)
where T : class
{
if (item == null)
return false;
return set.Add(item);
}
}
Затем вы можете сделать это:
HashSet<object> test = new HashSet<object>();
test.AddNonNull(null); //Will return false;
В любом случае, вы можете использовать кодовые контракты в .NET 4.0 для предотвращения NULL
значений, которые будут добавлены в коллекцию. Таким образом, вы также получите проверку времени компиляции, правильный ли код (используя статический анализ, предусмотренный кодом договоров):
public class MyClass {
private List<Something> nonNullList;
[ContractInvariantMethod]
void NonNullEntries() {
Contract.Invariant(Contract.ForAll(nonNullList, el => el != null));
}
public void Add(Something el) {
Contract.Requires(el != null);
}
}
Способ, отмеченный ContractInvariTMethod
Указывает состояние, которое должно быть В любое время держится (нет null
элементов в списке). Я считаю, что статический анализ не может рассуждать об этом (из-за Forall
), но я могу ошибиться. Тем не менее, это, безусловно, может проверить, вы вызываете добавить
методом с правильными (ненутренными) аргументами.
Поскольку вы отметили этот вопрос с помощью generics
, я полагаю, вы ищете общую коллекцию. Такой коллекции не существует в платформе .NET просто потому, что типы значений не могут быть null
, поэтому я думаю, вам придется откатить свой собственный, добавив ограничение ограничения на общий тип, который он принимает.
A System.Collections.Generics.Dictionary
не позволяет добавлять null
для TKey
(вызывает исключение). Вам придется проигнорировать TValue
s тогда в вашем сценарии, если вы собираетесь использовать его таким образом, и функциональность будет аналогична Hashset
, за исключением причудливого набора операции конечно.
Конечно, это немного неуклюже, но, возможно, это подходящий обходной путь для вас, прежде чем вы сможете придумать свой собственный модный тип коллекции.
Два варианта:
Edit: Извините, я пропустил, что ему нужен набор, а не коллекция. По крайней мере, предпочтительный элемент, который я перечислил, все еще действителен. :)
В методе, который добавляет элементы в коллекцию, бросьте ArgumentNullException
, если они вызываются с недействительным значением.
Вытекает из Collection
и переопределяет InsertItem
и SetItem
для сброса ArgumentNullException
, если их значение является нулевым.
Что ж, первоначальная причина, по которой я выбрал OpenID, заключалась в том, чтобы кто-то другой мог обработать как можно больше реализации и безопасности аутентификации для меня.
После просмотра OpenID появляется что-то называемое «немедленным запросом» ( http://openid.net/specs/openid-authentication-2_0.html#anchor28 ).
При запросе аутентификации Доверяющая сторона МОЖЕТ запросить, чтобы ОП не взаимодействовала с конечным пользователем. В этом случае ОП ДОЛЖЕН немедленно ответить либо утверждением, что аутентификация успешна, либо ответом, указывающим, что запрос не может быть выполнен без дальнейшего взаимодействия с пользователем.
Из-за этого я думаю, что я мог бы просто сохранить URL-адрес openID пользователя в файле cookie и использовать немедленный запрос, чтобы увидеть, аутентифицирован ли пользователь или нет. Таким образом, мне не нужно ничего делать с моей базой данных, или реализовать любую логику для предотвращения захвата сеанса долгоживущего файла cookie.
Этот метод выполнения, по-видимому, является способом, которым OpenID предлагает его выполнить с помощью документа Best Practices .
-121--2308818-В целом сайт становится проще переваривать для остальной части Интернета. Данные можно использовать повторно, объединять, создавать перекрестные ссылки и сохранять.
Простым примером было бы иметь в любом месте на сайт широту и долготу (гео). С помощью микроформатов любой, кто ищет эту широту и долготу, может быть легко связан со своим веб-сайтом, увеличивая трафик, узнавая об этом человеке/компании и позволяя пользователям легко сохранять эту информацию. (Хотя я сталкивался с этим мало лично, это скорее «будущее» вещей, чем настоящее. Но всегда хорошо быть в курсе событий).
Вторым примером может быть визитная карточка (hCard), где браузер может легко сохранить и перенести ее в адресную книгу, так что только один визит на сайт и посетитель имеет информацию, сохраненную локально. Особенно полезно, если они получают хиты с мобильного телефона.
-121--4903969-Мне неизвестна коллекция .NET, которая делает это, поскольку на основе переданного типа значение null фактически является допустимой записью, таким образом, добавление успешно выполнено.
Я, скорее всего, начну с класса System.Collections.ObjectModel.Collection для развертывания собственного.
Вам придется создавать свои собственные. Если вы хотите, чтобы Add возвращала bool (был ли элемент не null и, следовательно, добавлен или наоборот), вам придется начать с нуля. Я бы рекомендовал наследоваться от List и бросать ArgumentNullExceptions. То есть, если вы действительно не хотите добавлять нули, исключения могут быть лучшим способом и, конечно, более простым.