2010-03-19 51 views
33

我有一段代碼,我需要找出如果一個給定的類型實現IEnumerable<T>(我不關心T)F#當量的C#的typeof的(IEnumerable的<>)

我已經試過(t:System.Type如果你想知道)

let interfaces = t.GetInterfaces() 
let enumerbale = 
    interfaces.Any(fun t -> 
     t.GetGenericTypeDefinition() = typeof<IEnumerable<>> 
    ) 

但這不會編譯(編譯不喜歡<>)。我然後嘗試

let interfaces = t.GetInterfaces() 
let enumerbale = 
    interfaces.Any(fun t -> 
     t.GetGenericTypeDefinition() = typeof<IEnumerable<'a>> 
    ) 

但得到的警告'a是對obj的約束。我不想弄清楚是否實施了IEnumerable<obj>,但是IEnumerabl<>

任何人都知道的解決方案,順便說一句,也可以自由地評論上面的代碼。

+0

http://stackoverflow.com/questions/1652050/generic-type-definition-發現之一syntax-on-f – 2010-03-20 22:40:06

回答

49

這應該工作:

typedefof<System.IEnumerable<_>> 

編輯

正如托馬斯指出,沒有什麼特別之處這裏_通配符; F#推斷類型obj是此上下文中最通用的適用類型,因此這與使用typedefof<System.IEnumerable<obj>>相同。但是在某些情況下,這種方式可能有點阻礙。例如,如果你定義了一個接口type I<'a when 'a :> I<'a>> = interface end,那麼你不能使用typedefof<I<_>>,因爲I<obj>不滿足通用約束條件,F#不能推斷出另一個更合適的類型。這可能會發生,即使沒有遞歸約束(例如type I<'a when 'a : struct and 'a :> System.ICloneable> = interface end。這與C#的方法形成對比,在類似的情況下它完全正常)

至於你的代碼本身,我想你會想做一些其他的改變, 。同樣,如確保接口調用GetGenericTypeDefinition前通用以下是我會寫的測試功能:

(fun t -> t.IsGenericType && (t.GetGenericTypeDefinition() = typedefof<_ seq>)) 
+0

你的解決方案救了我從另一個問題:)與不那麼有用的errormessage「不支持,由於當前狀態的對象」這是一種說法不能調用getgenerictypedefinitionón非泛型類型 – 2010-03-19 22:09:11

17

據我所知,F#沒有任何等同於C#的typeof(IEnumerable<>)這是因爲這是C#明確支持的一種特殊語法,在F#中,typeof是一個普通函數,類型參數需要是完全指定的類型。 eneric類型定義編程是這樣的:

let t = typeof<IEnumerable<obj>> 
let genericT = t.GetGenericTypeDefinition() 

IEnumerable<'a>您的解決方案的問題是,F#編譯器仍然需要找到一些具體類型的使用(如泛型類型定義是不是有效的類型)。如果類型推斷推斷類型參數不受任何限制,則它使用默認類型,即obj。我不知道typedefof<IEnumerable<_>>,這是非常有用的!無論如何,請注意下劃線在這裏沒有任何特別的含義 - 實際的類型參數仍然是IEnumerable<obj>,但typedefof函數在場景後面調用GetGenericTypeDefinition

+0

THanks for澄清_ – 2010-03-19 20:46:51

相關問題