为什么Where-Object会评估源对象上的* all *属性而不仅仅是相关属性?

时间:2012-01-27 14:12:20

标签: powershell

我有一个DLL程序集,它返回一个List(EmailItem)。 EmailItem是一个自定义类,包含一些由于执行所花费的处理时间而延迟加载的属性。根据我的业务需求,他们基本上是帮助者。

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

但是,如果我使用PoSh检索这些类的集合,然后使用Where-Object过滤它们,即使它们未在Where-Object scriptblock或脚本中的任何其他位置引用,也会评估这些属性中的每一个。我尝试过编写自定义过滤器但遇到相同的行为。甚至投射我关心使用Select-Object的值也会做同样的事情。

我最好的猜测是,对象正在转换为PSObjects,而PowerShell正在填充属性。

任何想法如何避免这个或为此脚本关闭它?我正在加入"轻量级"不包含这些帮助程序的对象,但这只是为了支持我最喜欢的Windows脚本语言而烦人的工作量。

感谢您的任何提示!

2 个答案:

答案 0 :(得分: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的输出为False四次。 命令3的输出为False四次。 命令4的输出导致在每个对象上计算LazyProperty。 命令5的输出为True四次。

我也尝试将这些对象管道化为“select One,LazyEvaluated”,并且不会导致对LazyProperty进行评估。

答案 1 :(得分:2)

我认为你不能改变where-object的行为,但你可以尝试用foreach和IF代替它:

例如

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