讀了[url= lippert[/url]的這帖:[url= maintenance[/url]之後,心裡一陣寒——我自己寫的**裡就有幾乎一模一樣的邏輯。
eric的帖裡舉的不好的例子:
public static class streamreaderextensions
}
我的**:
///
/// reads the stream as lines of strings from the current
/// position to the end of the stream.
///
/// the stream to read from
/// an enumerator of the lines of strings.
public static ienumerablelines( this streamreader reader )
}
事實上我的還更糟糕一些,沒做null檢查。寫擴充套件方法的時候我總是寫著寫著就忘了:擴充套件方法不是成員方法,作為「this」的引數需要做null檢查。
eric對他所舉的例子指出了幾個不足:
1、[b]null檢查不是在方法呼叫時執行,而是在迭代器第一次移動的時候才執行的[/b];
2、while迴圈在一行塞了太多邏輯,可以分開來寫;
3、通過basestream來改變了底下的流的位置,不符合習慣上對流的使用方式;
4、呼叫者需要知道太多細節,例如必須知道何時這個迭代器結束了,在結束後由呼叫者來關閉流;
……等。
第4點我在寫我那個程式時也知道這裡有問題,但沒想出好的解決辦法。假如我就是要特意把流設定到某個位置之後再呼叫lines(),該怎麼辦呢?或者說假如原本就不存在乙個實際檔案(例如stdin),那就無法用檔名來指定引數了,又怎麼辦呢?
帶有yield關鍵字的方法(也就是generator),其方法體在generator被呼叫時是不會被執行的;只有當其返回的iterator的movenext()方法被初次呼叫時才會執行。
舉例來說,這樣:
using system;
using system.collections.generic;
static class program
}static void main( string[ ] args )
}}
輸出的結果會是:
[code]after foo(), before foreach
starting enumerator01
2[/code]
了解c#的generator的實現方式就不難理解這個行為的**。c#的generator實際上是個由編譯器自動生成的實現了ienumerable介面的有限狀態機。也就是說generator裡實際上只有乙個return new ...,或許還會有些引數賦值,卻沒有任何別的內容。原始碼裡寫在generator裡的邏輯都生成到了那個有限狀態機物件裡,也就是外界看到的迭代器裡。如果要對引數做檢查,恐怕還就是eric說的,提供乙個公有方法作為介面,在裡面檢查引數的正確性,然後再呼叫乙個私有的generator來完成實際迭代工作。
用foogenerator的例子說,假如max小於0是不符合要求的,那麼應該這樣寫:
public static ienumerablefoogenerator( int max )
return foogeneratorcore( max );
}private static ienumerablefoogenerator( int max )
}
JS彈出視窗不會被Maxthon遮蔽的方法
window.showmodelessdialog 網頁,scroll 0 status 0 help 0 resizable 0 dialogwidth 0px dialogheight 0px 0000 sfeatures 可選引數,型別 字串。用來描述對話方塊的外觀等資訊,可以使用以下的乙個或...
執行頁面當前的內容會不會被清空
我是div,哈哈哈 問題 任何時候使用document.write,頁面會不會被清空?document.write 111 document.write 222 1 這種情況是可以列印出來,頁面當前的內容不會被清空 window.onload function 2 兩次document.write ...
JS中的Generator 筆記
語法上,首先可以把它理解成,generator 函式是乙個狀態機,封裝了多個內部狀態。執行 generator 函式會返回乙個遍歷器物件,也就是說,generator 函式除了狀態機,還是乙個遍歷器物件生成函式。返回的遍歷器物件,可以依次遍歷 generator 函式內部的每乙個狀態。generat...