Во-первых, Эрик абсолютно прав: если вы беспокоитесь о производительности, вам нужно измерить ее .Выясните, что именно вы хотите измерить, и запишите, что происходит для каждого изменения, которое вы вносите в свой код.Существуют различные аспекты бенчмаркинга, на которые у меня сейчас нет времени, но ключевым из них, вероятно, является обеспечение того, чтобы тесты выполнялись достаточно долго, чтобы они были значимыми - если ваш тест занимает всего 50 мс, вывряд ли удастся отличить ваш код от шума.
Теперь, если вы используете LINQ to Objects, вы почти наверняка не хотите использовать деревья выражений вообще.Придерживайтесь делегатов - это то, что LINQ to Objects использует в любом случае.
Теперь, что касается реструктуризации ... если у вас есть общий предикат, то вы можете отфильтровать свой список по этому, чтобы начать сс новым IEnumerable<T>
.Предикат будет применен лениво, поэтому он не будет иметь никакого значения для скорости выполнения, но он может сделать ваш код более читабельным.Это может замедлить работу очень незначительно , поскольку это создаст дополнительный уровень косвенности, когда вы фактически получите два разных предложения where
.
Если результат применения фильтров будет иметьочень мало результатов, вы можете захотеть его материализовать (например, позвонив по номеру ToList
) и запомнить результат - таким образом вам не нужно снова запрашивать все для второго запроса.
Тем не менее, big преимущество, которое я вижу, заключается в том, чтобы вызывать Single
только один раз для каждого запроса.В настоящее время вы выполняете весь запрос для каждого отдельного свойства - это явно неэффективно.
Вот ваш код, соответственно переписанный - и тоже используете инициализатор коллекции:
PersonDetails d = new PersonDetails
{
new Person {Age = 29, Born = "Timbuk Tu", First = "Joe",
Last = "Bloggs", Living = "London"},
new Person { Age = 29, Born = "Timbuk Tu", First = "Foo",
Last = "Bar", Living = "NewYork" }
};
var peopleOfCorrectAge = d.Where(a => a.Age == 29);
var londoners = peopleOfCorrectAge.Where(p => p.Living == "London");
var newYorkers = peopleOfCorrectAge.Where(p => p.Living == "New York");
var londoner = londoners.Single();
var newYorker = newYorker.Single();
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
londoner.Age, londoner.First,
londoner.Last, londoner.Living, londoner.Born);
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
newYorker.Age, newYorker.First,
newYorker.Last, newYorker.Living, newYorker.Born);
В качестве альтернативы дляВ последнем разделе инкапсулируем «выписывание одного человека»:
DisplayPerson(londoners.Single());
DisplayPerson(newYorkers.Single());
...
private static void DisplayPerson(Person person)
{
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
person.Age, person.First,
person.Last, person.Living, person.Born);
}