2011-03-11 57 views
22

我正在閱讀Jon Skeet的書'C#in Depth,2nd Edition'。他說,我們可以調用使用兩種解決動態參數的擴展方法,就像如何調用動態類型的擴展方法?

dynamic size = 5; 
var numbers = Enumerable.Range(10, 10); 
var error = numbers.Take(size); 
var workaround1 = numbers.Take((int) size); 
var workaround2 = Enumerable.Take(numbers, size); 

然後他說:「如果你想調用與動態值作爲隱含this值的擴展方法這兩種方法都將工作」 。我不知道如何實現它。

非常感謝。

+11

男人,現在是不是隻是票?你閱讀Jon Skeet的一本書,並從Jon Skeet那裏得到一些你不清楚的答案。 – 2011-03-11 08:59:04

+4

我們需要一個jon-skeet標籤嗎? – Myster 2011-11-01 20:11:41

回答

38

像這樣:

dynamic numbers = Enumerable.Range(10, 10); 
var firstFive = Enumerable.Take(numbers, 5); 

換句話說,只是把它作爲一個靜態方法,而不是作爲一個擴展方法。

或者如果你知道一個合適的類型參數,你可以只投它,這我通常使用一個額外的變量做:

dynamic numbers = Enumerable.Range(10, 10); 
var sequence = (IEnumerable<int>) numbers; 
var firstFive = sequence.Take(5); 

...但如果你處理動態類型,你可能不知道序列元素的類型,在這種情況下,第一個版本基本上可以讓「執行時間編譯器」找出它。

+1

想必你可以這樣做:((IEnumerable )數字)。拿(5)? – Massif 2011-03-11 08:54:40

+1

@Massif:是的,你也可以這樣做。將編輯。 – 2011-03-11 08:58:34

3

擴展方法只是一個語法糖,它將被轉換爲由c#編譯器調用的常規方法。此轉換取決於當前的語法上下文(哪些名稱空間是通過使用語句導入的)。

動態變量是由運行時處理的。這次,CLR無法獲得足夠的語法上下文信息來決定使用哪種擴展方法。所以,這是行不通的。