Сделайте NameValueCollection доступным для LINQ Query

Это случилось со мной, когда я импортировал проект Java 1.8 из Eclipse Luna в Eclipse Kepler.

  1. Щелкните правой кнопкой мыши по проекту> Путь сборки> сконфигурировать путь сборки ...
  2. Выберите вкладку «Библиотеки», вы увидите Java 1.8 jre с ошибкой
  3. Выберите java 1.8 jre и нажмите кнопку «Удалить»
  4. Добавить библиотеку ...> JRE System Library > Далее> рабочая область по умолчанию> Готово
  5. Нажмите OK, чтобы закрыть окно свойств
  6. Перейдите в меню проекта> Очистить ...> OK

Et voilà, это сработало для меня.

60
задан Matteo Mosca 16 December 2013 в 12:25
поделиться

4 ответа

Необходимо "снять" недженерик IEnumerable к IEnumerable<string>. Было предложено использовать OfType, но это - метод фильтрации. То, что Вы делаете, является эквивалентом броска, для которого существует Cast оператор:

var fields = RequestFields().Cast<string>();

, Поскольку Frans указал, это только обеспечивает доступ к ключам. Необходимо было бы все еще индексировать в набор для значений. Вот дополнительный метод для извлечения KeyValuePair с из NameValueCollection:

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key]));
}

Редактирование: В ответ на запрос @Ruben Bartelink, вот то, как получить доступ к полному набору значений для каждого ключа с помощью [1 110]:

public static ILookup<string, string> ToLookup(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    var pairs =
        from key in collection.Cast<String>()
        from value in collection.GetValues(key)
        select new { key, value };

    return pairs.ToLookup(pair => pair.key, pair => pair.value);
}

, С другой стороны, кортежи C# 7.0 использования:

public static IEnumerable<(String name, String value)> ToTuples(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return
        from key in collection.Cast<string>()
        from value in collection.GetValues(key)
        select (key, value);
}
90
ответ дан Bryan Watts 16 December 2013 в 12:25
поделиться

AsQueryable должен взять IEnumerable<T>, дженерик. NameValueCollection реализации IEnumerable, который отличается.

Вместо этого:

{
    NameValueCollection nvc = RequestFields();
    IQueryable queryable = nvc.AsQueryable();
}

Попытка OfType (это принимает неуниверсальный интерфейс)

{
    NameValueCollection nvc = RequestFields();
    IEnumerable<string> canBeQueried = nvc.OfType<string>();
    IEnumerable<string> query =
       canBeQueried.Where(s => s.StartsWith("abc"));
}
11
ответ дан Ruben Bartelink 16 December 2013 в 12:25
поделиться

Проблема состоит в том, что набор реализует IEnumerable (в противоположность IEnumerable<T>), и перечисление набора возвращает ключи, не пар.

На вашем месте, я использовал бы Dictionary<string, string>, который является счетным и может использоваться с LINQ.

4
ответ дан Alexander Trauzzi 16 December 2013 в 12:25
поделиться

Словарь, вероятно, на самом деле ближе к тому, что вы хотите использовать, поскольку он фактически выполняет больше ролей, которые выполняет NameValueCollection. Это вариант решения Брайана Уоттса:

public static class CollectionExtensions
{
    public static IDictionary<string, string> ToDictionary(this NameValueCollection source)
    {
        return source.Cast<string>().Select(s => new { Key = s, Value = source[s] }).ToDictionary(p => p.Key, p => p.Value); 
    }
}
8
ответ дан 24 November 2019 в 17:42
поделиться
Другие вопросы по тегам:

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