У меня есть метод, который возвращает ILookup
. В некоторых случаях я хочу вернуть пустой ILookup
в качестве раннего выхода. Каков наилучший способ создания пустой ILookup
?
Пустой ILookup <K, T>
Ответ 1
В дополнение к ответам mquander и Vasile Bujac вы можете создать приятный, простой синглтон- esque EmptyLookup<K,E>
следующим образом. (По моему мнению, нет никакой пользы для создания полной реализации ILookup<K,E>
в соответствии с ответом Василе.)
var empty = EmptyLookup<int, string>.Instance;
// ...
public static class EmptyLookup<TKey, TElement>
{
private static readonly ILookup<TKey, TElement> _instance
= Enumerable.Empty<TElement>().ToLookup(x => default(TKey));
public static ILookup<TKey, TElement> Instance
{
get { return _instance; }
}
}
Ответ 2
Нет встроенного, поэтому я просто напишу метод расширения, который запускает что-то вдоль строк new T[0].ToLookup<K, T>(x => default(K));
Я сильно сомневаюсь, что вернувшийся null будет более правильным. Это почти никогда не означает, что вы хотите вернуть null из метода, который возвращает коллекцию (в отличие от пустой коллекции). Я не мог больше не соглашаться с людьми, которые предлагают это.
Ответ 3
Вы можете создать одноэлементный класс для пустых поисков.
using System.Linq;
public sealed class EmptyLookup<T, K> : ILookup<T, K>
{
public static readonly EmptyLookup<T, K> Instance { get; }
= new EmptyLookup<T, K>();
private EmptyLookup() { }
public bool Contains(T key) => false;
public int Count => 0;
public IEnumerable<K> this[T key] => Enumerable.Empty<K>();
public IEnumerator<IGrouping<T, K>> GetEnumerator()
=> Enumerable.Empty<IGrouping<K, V>>().GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
}
тогда вы можете написать код так:
var x = EmptyLookup<int, int>.Instance;
Преимущество создания нового класса заключается в том, что вы можете использовать оператор "is" и проверять равенство типов:
if (x is EmptyLookup<,>) {
// ....
}
Ответ 4
Основываясь на ответе LukeH, я бы создал статический класс Lookup
с помощью Empty<TKey, TElement>
. Таким образом, вы можете использовать так же, как Enumerable.Empty<T>
.
public static class Lookup
{
public static ILookup<TKey, TElement> Empty<TKey, TElement>()
=> Enumerable.Empty<TElement>().ToLookup(x => default(TKey));
}
Пример использования: Lookup.Empty<string, string>()
Ответ 5
Создайте пустой список, затем выполните ToLookup() на нем, например:
List<Point> items = new List<Point>();
ILookup<int, int> lookup = items.ToLookup(p => p.X, p => p.Y);
Удачи!
Ответ 6
Или что-то еще в духе LINQ:
public static class Utility
{
public static ILookup<TKey, TElement> EmptyLookup<TKey, TElement>(Func<TKey, TKey> keySelector,
Func<TKey, TElement> elementSelector)
{
return Enumerable.Empty<TKey>().ToLookup(keySelector, elementSelector);
}
}
Ответ 7
Вы можете вернуть null
или исключение
Но вы должны отметить это в комментарии к классу
Добавлено: + Это более очевидно, чем какой-либо метод расширения