Patrick Skelton Ответов: 3

Как вернуть одно значение из списка с помощью LINQ?


Я новичок в LINQ и знаю, что это (должно быть?) простой вопрос, но я борюсь с синтаксисом простого запроса LINQ. Следующий сокращенный код показывает, чего я пытаюсь достичь:

public class Fruit
{
    public int ID { get; set; } = 0;
    public Name { get; set; } = String.Empty;
}

public class Fruits
{
    public List<Fruit> ListOfFruits = new List<Fruit>()
    {
        new Fruit { ID = 0, Name = "Apple" },
        new Fruit { ID = 1, Name = "Orange" },
        new Fruit { ID = 2, Name = "Banana" },
    }

    public int GetIDFromName( string fruitName )
    {
        // What goes here?
    }
}


Как новичок в этом деле, я был бы признателен за любой совет. В частности, я хотел бы получить решение, которое использует специальные ключевые слова LINQ ('select',' where ' и т. д.), а также стандартные функции LINQ C# (Select (), Where () и т. д.), чтобы я мог сравнить эти два подхода.

Кажется, существует очень мало примеров, которые показывают два подхода бок о бок для сравнения, и я также смущен тем, когда один подход лучше другого. Для простой последовательности я хотел бы выбрать один путь и придерживаться его.

Добрые пожелания ~ Патрик

Что я уже пробовал:

Я пробовал такие выражения, как...

ListOfFruits.Select( f => f.ID ).Where( ... )


... но я даже не могу заставить это скомпилировать, потому что, похоже, указав только идентификатор в Выбрать пункт, я перестаю быть в состоянии ссылаться на имя в Где пункт.

3 Ответов

Рейтинг:
26

eddieangel

ListOfFruits.FirstOrDefault(x => x.Name == "Apple").ID

Вы также можете загрузить FirstOrDefault в объект и проверить наличие null, прежде чем пытаться получить доступ к идентификатору.

Как было предложено, чтобы избежать исключения NullRef, вы можете сделать несколько вещей:

Если вы используете версию VS с компилятором Roslyn:

ListOfFruits.FirstOrDefault(x => x.Name == "Apple")?.ID


В противном случае более подробный метод:

var fruit = ListOfFruits.FirstOrDefault(x => x.Name == "Apple");
if (fruit != null)
{
     return fruit.ID;
}

return 0;


Это не единственная дорога в Рим, вы также можете использовать Single (), SingleOrDefault() или First(). Одинокий ожидает единственного ответа, который должен быть там, я обнаруживаю, что чаще всего тяготею к FirstOrDefault.


Thomas Daniels

Это правильно, но обратите внимание, что он вызовет исключение, когда возвращаемое значение FirstOrDefault равно null.

eddieangel

Улучшил решение, чтобы учесть этот случай явно, спасибо за предложение.

Рейтинг:
17

Matt T Heffron

Поскольку вы просили обе синтаксические формы:

public int GetIDFromName( string fruitName )
{
  // LINQ functions:
  Fruit f = ListOfFruits.FirstOrDefault(x => x.Name == fruitName);
  // LINQ SQL-ish:
  Fruit f = (from x in ListOfFruits where x.Name == fruitName select x).FirstOrDefault();
  // (common to both):
  return f != null ? f.ID : -1;   // some value to indicate no such fruit
}
Это не очень хороший случай для сравнения одного синтаксиса с другим...


Patrick Skelton

Вы комментируете, что это не особенно хороший случай для сравнения двух вариантов синтаксиса. Верно ли тогда сказать, что, если я хочу последовательности, мне лучше остаться с простым синтаксисом C#? Является ли она более гибкой, чем чистая форма SQL-ish?

Matt T Heffron

(Я был "вне сети"...)
В целом, я думаю, что каждая из этих двух форм имеет свои преимущества, и есть некоторые запросы, которые могут быть выражены только в синтаксисе метода (например, "FirstOrDefault()" выше).
Например, (для меня) форма SQL лучше, если есть соединения.
Это не тот момент, когда вы должны быть строги в отношении общей согласованности выбора синтаксической формы.
Используйте то, что имеет смысл в каждом контексте.

Patrick Skelton

- Спасибо, Мэтт. Это очень полезно.

Рейтинг:
11

Neha Ambasta

Мы также можем использовать First вместо FirstOrDefault.Мы можем написать приведенный выше код следующим образом

public int GetIDFromName( string fruitName )
{
// LINQ функции:
Fruit f = ListOfFruits.Первый(x => x.Name == фруктовое имя);
// LINQ SQL-ish:
Фрукт Ф = (С Х В, где Х ListOfFruits.Имя == fruitName выберите X).Первый();
// (общее для обоих):
вернуть f != null ? f.ID : -1; / / некоторое значение, указывающее на отсутствие такого фрукта
}


F. Xaver

.First выдаст исключение, если нет фрукта с таким именем, поэтому -1 никогда не возвращается

[no name]

Ладно, Спасибо Ксавье.