Why does the Where-Object evaluate * all * the properties of the original object, and not just the corresponding ones?

I have a DLL assembly that returns a list (EmailItem). EmailItem is a custom class that includes some properties that are lazy to load due to the processing time that they execute to execute. They are mostly helpers based on my business requirements.

When I work with these objects in my Windows and console applications, these properties are quietly waiting for a call there.

However, if I use PoSh to retrieve a set of these classes, then use the Where-Object to filter them, each of these properties is evaluated, even if they are not specified in the Where-Object script block or elsewhere in the script. I tried to write a custom filter, but experienced the same behavior. Even projecting values ​​that worry me about using Select-Object does the same thing.

My best guess is that objects are converted to PSObjects, and PowerShell populates the properties.

Any ideas how to avoid this or disable it for this script? I am in the process of adding “lightweight” objects that these helpers do not include, but this annoys the amount of work just to support my favorite Windows scripting language.

Thanks for any tips!

+4
source share
2 answers

This is not at all true. In your case, there is something more subtle.

I defined this class:

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"; } } } } 

Then the following commands were executed:

 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 } 

The result of team 2 was False four times. Exiting team 3 was false four times. The result of team 4 caused LazyProperty to be evaluated on every object. Exiting Team 5 was True four times.

I also tried passing these objects to "select One, LazyEvaluated", and this did not trigger a LazyProperty evaluation.

+5
source

I do not think that you can change the behavior of the where object, but you can try replacing it with foreach and IF:

eg

 foreach ($emailitem in $emailitems){ if ($emailitem.subject -match 'important'){$emailitem} } 
+2
source

Source: https://habr.com/ru/post/1393366/


All Articles