Почему Where-Object оценивает * все * свойства исходного объекта, а не только соответствующие? - PullRequest
4 голосов
/ 27 января 2012

У меня есть сборка DLL, которая возвращает список (из EmailItem).EmailItem - это пользовательский класс, который включает некоторые свойства, которые загружаются из-за времени обработки, которое они тратят на выполнение.Они в основном являются помощниками, основываясь на моих бизнес-требованиях.

Когда я работаю с этими объектами в своих службах Windows и приложениях консоли, эти свойства спокойно ожидают вызова.

Однако, если яиспользуйте PoSh для получения набора этих классов, затем используйте Where-Object для их фильтрации, каждое из этих свойств оценивается, даже если на них нет ссылок в блоке скриптов Where-Object или где-либо еще в сценарии.Я пытался написать собственный фильтр, но у меня такое же поведение.Даже проецирование значений, которые мне нужны, с помощью Select-Object делает то же самое.

Мое лучшее предположение о том, что объекты преобразуются в PSObjects, а PowerShell заполняет свойства.Есть идеи, как этого избежать или отключить для этого сценария?Я нахожусь в процессе добавления «облегченных» объектов, которые не включают в себя эти помощники, но это надоедливый объем работы только для поддержки моего любимого языка сценариев Windows.

Спасибо за любые советы!

Ответы [ 2 ]

5 голосов
/ 27 января 2012

В общем, это не так.В вашем случае происходит нечто более тонкое.

Я определил этот класс:

namespace Lazy
{
    public class LazyClass
    {
        public int One { get { return 1; } }
        public bool LazyEvaluated { get; private set; }
        public string LazyProperty { get { LazyEvaluated = true; return "Lazy"; } }
    }
}

Затем запустил эти команды:

1: $lazy = 1..4 | % { New-Object Lazy.LazyClass }
2: $lazy | % { $_.LazyEvaluated }
3: $lazy | ? { $_.One -eq 1 } | % { $_.LazyEvaluated }
4: $lazy
5: $lazy | ? { $_.One -eq 1 } | % { $_.LazyEvaluated }

Вывод команды 2был ложным четыре раза.Выход из команды 3 был False четыре раза.Вывод команды 4 вызвал LazyProperty для оценки каждого объекта.Вывод команды 5 был равен True четыре раза.

Я также попытался передать эти объекты в «select One, LazyEvaluated», и это не привело к оценке LazyProperty.

2 голосов
/ 27 января 2012

Я не думаю, что вы можете изменить поведение where-object, но вы можете попробовать заменить его на foreach и IF:

например

foreach ($emailitem in $emailitems){
     if ($emailitem.subject -match 'important'){$emailitem}
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...