2012-01-27 42 views
4

我有一个DLL程序集,返回一个列表(EmailItem)。 EmailItem是一个自定义类,它包含一些由于执行处理时间而导致的延迟加载的属性。他们基本上是基于我的业务需求的助手。为什么Where-Object会评估源对象上的所有*属性而不是相关的属性?

当我在Windows服务和控制台应用程序中使用这些对象时,这些属性静静地坐在那里等待被调用。

但是,如果我使用PoSh检索这些类的集合,然后使用Where-Object对其进行筛选,则即使它们未在Where对象脚本块或脚本中的其他任何地方被引用,也会对这些属性进行评估。我已经尝试编写自定义过滤器,但体验相同的行为。即使投射我关心使用Select-Object的值也会做同样的事情。

我最好的野驴猜测是对象正在转换为PSObjects并且PowerShell正在填充属性。

任何想法如何避免此问题或关闭此脚本?我正在添加不包含这些助手的“轻量级”对象,但这只是为了支持我最喜欢的Windows脚本语言而烦人的工作量。

感谢您的任何提示!

+0

“即使使用Select-Object来投影我所关心的值也是一样的。”真?!这不应该发生....这使得选择对象而不是无用的! – Tom 2012-01-27 14:26:43

+1

你的'Where-Object'语句是什么样的? – Rynant 2012-01-27 15:40:37

+1

我的简单测试表明'Where-Object'不像你描述的那样工作。将结果写入控制台时,是否有可能实际评估了您的属性?然后所有的属性都可以被评估。 – 2012-01-27 16:13:01

回答

5

这似乎并没有一般来说是真实的。在你的情况下有一些更微妙的事情发生。

我定义这个类:

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的输出结果为真4次。

我也尝试将这些对象滚动到“select One,LazyEvaluated”,并且不会导致评估LazyProperty。

+0

感谢您做这个级别的研究!下周我会修改我的代码,看看我能否找到与我的情况不同的东西。很奇怪,当我使用foreach()迭代项目时,我没有遇到这个问题。如果我没有学到更好的东西,我会回来并将其标记为答案,因为这个问题通常与PoSh并不相符。 – 2012-01-27 21:39:11

2

我不认为你可以更改对象的行为,但你可以尝试用一个foreach替换的是,和IF:

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

我感到很傻,我没有尝试过。我想我总是会想到使用PowerShell的“管道”。事实上,这确实解决了这个问题。我不明白。具有讽刺意味的是,我还学会了如何在上游进一步推送查询,所以我不再需要在PoSh中进行过滤。 – 2012-01-27 21:35:31

相关问题