2012-01-27 23 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

相關問題