4

I have a DLL assembly that returns a List(of EmailItem). EmailItem is a custom class that includes some properties that lazy load due to the processing time they take to execute. They're basically helpers based on my business requirements.

When I work with these objects in my Windows Service and console applications, these properties sit there quietly waiting to be called.

However if I use PoSh to retrieve a set of these classes, then use Where-Object to filter them, each of these properties is evaluated even though they are not referenced in the Where-Object scriptblock or anywhere else in the script. I've tried writing a custom filter but experience the same behavior. Even projecting the values I care about using Select-Object does the same thing.

My best wild-ass guess is that the objects are being converted to PSObjects and PowerShell is populating the properties.

Any ideas how to avoid this or turn it off for this script? I'm in the process of adding "lightweight" objects that don't include these helpers, but that's an annoying amount of work just to support my favorite Windows scripting language.

Thanks for any tips!

4
  • "Even projecting the values I care about using Select-Object does the same thing." Really?! This should not be happening....this renders select-object rather usless! Commented Jan 27, 2012 at 14:26
  • 1
    What does your 'Where-Object` statement look like? Commented Jan 27, 2012 at 15:40
  • 1
    My simple test shows that Where-Object does not work as you describe. Is it possible that your properties are actually evaluated when the results are being written to the console? Then all properties can be evaluated indeed. Commented Jan 27, 2012 at 16:13
  • Not a .net guru by any strech of the imagination, but I do know that once it goes through select-object, the original object type is lost. Without any object type information to know what to expect, and given the possibility that in a generic collection or array all the objects aren't necessarily the same, and the possibility that a property could be an alias of, or calculated from another property it might not have any choice but to evaluate everything. Or, I may not have any idea what I'm talking about. Commented Jan 27, 2012 at 22:18

2 Answers 2

5

This does not appear to be true in general. There is something more subtle going on in your case.

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 ran these commands:

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 output from command 2 was False four times. The output from command 3 was False four times. The output from command 4 caused LazyProperty to be evaluated on each object. The output from command 5 was True four times.

I also tried piping these objects into "select One,LazyEvaluated" and that did not cause LazyProperty to be evaluated.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for doing this level of research! I will revist my code next week and see if I can find what is different in my case. It's curious that when I iterated over the items using foreach(), I did not experience the issue. If I don't learn anything better, I shall come back and mark this as the answer because it seems fairly definitive that the issue is not with PoSh, in general.
2

I don't think you can change the behaviour of where-object, but you might try replacing that with a foreach, and an IF:

eg

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

1 Comment

I feel silly that this didn't occur to me to try. I guess I just always think "pipes" with PowerShell. This did, in fact, work around the issue. I don't understand it. Ironically, I also learned how to push the query further upstream, so I don't need to do the filtering in PoSh anymore.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.