2010-05-14 47 views
4

在具有延遲加載屬性的類,如:檢查延遲加載的特性進行了實例化

private Collection<int> someInts; 

public Collection<int> SomeInts 
{ 
    get 
    { 
     if (this.someInts == null) this.someInts = new Collection<int>(); 
     return this.someInts; 
    } 
} 

是否值得還具有一個特性,如:

public bool SomeIntsExist 
{ 
    get { return (this.someInts != null && this.someInts.Count > 0); } 
} 

,然後使用該屬性..例如:

if (thatClass.SomeIntsExist) 
{ 
    // do something with thatClass.SomeInts collection 
} 

或者這是過早的優化。它當然更容易喜歡的東西下面滾動,但它會實例化不必要的集合:

if (thatClass.SomeInts.Count > 0) 
{ 
    // do something with thatClass.SomeInts collection 
} 

是編譯器足夠聰明推測這樣的事情呢?有沒有更好的辦法?

+3

順便說一下,你的代碼不是線程安全的。多個線程可能同時發現後臺字段爲空,並且每個線程都會創建一個空集合。結果,後續代碼可能會使用由線程A創建的集合一段時間,直到線程B再次用空集合覆蓋它爲止。如果您需要線程安全,您必須使用某種形式的鎖定。 – 2010-05-14 12:22:04

+0

@Daniel,謝謝 - 好評。我意識到這些問題,但試圖保持簡單的例子:)。 – PaulG 2010-05-14 12:30:06

+0

@Daniel「順便說一句,你的代碼不是線程安全的」。大多數框架類的實例成員不是線程安全的,所以這沒什麼不尋常的。事實上,我認爲通常最好的做法是讓一個班級的用戶保持線程安全。 – Joe 2011-03-04 10:22:06

回答

2

的甚至延遲初始化屬性聽起來像是不成熟的優化。只有極少數情況下,我可以想到,延遲創建空集合有助於解決問題(假設您的示例不會過於簡化)。

但是,如果您必須延遲收集初始化,那麼您可能(甚至必須)優化Exists方法,因爲延遲初始化是一個關鍵要求。

0

如果延遲加載的類是一個很大的類,並且初始化需要一些時間....這樣的布爾結果。

bin在一個簡單的.net集合的情況下,它並沒有使我的意見。

1

編譯器不會自動將這些事情弄清楚。 這意味着,在最後一種情況下

if (thatClass.SomeInts.Count > 0) 
{ 
    // do something with thatClass.SomeInts collection 
} 

集合將被實例化。

所以,在我看來,這取決於它是多麼昂貴的初始化集合 - 在簡單情況下,它是不是真的很貴,但浪費的內存總和可能會...

1

如果您正在處理昂貴的數據檢索操作,例如,我會說這值得擁有像這樣的屬性。數據庫查詢。

但是,您的代碼存在缺陷。 SomeIntsExist只有當屬性已被預先訪問時,纔會真的給你正確的答案,如果該屬性是延遲加載,那麼確實可能是整數,但它們尚未加載。它應該重新命名爲IsInitialised。我知道這是一個例子,但它可能仍然值得指出:)

+0

我沒有按照你的第二段。SomeIntsExist屬性只有在集合已經實例化並且包含項目時纔會返回true,是否正確?我想你的意思是,如果它被多個線程訪問,它可能是一個問題? – PaulG 2010-05-14 10:16:46

+0

@Paul:我假設你會在訪問它時加載你的列表(因爲你提到了懶加載的屬性)。然而,再次查看你的代碼,你是懶惰的初始化屬性,在這種特殊情況下,除非你明確地需要檢查屬性是否已經初始化,否則你將無法獲得任何好處。 – James 2010-05-14 11:05:58

+0

感謝您澄清,並道歉我的混淆術語! – PaulG 2010-05-14 12:31:36