2010-03-19 11 views
33

जहाँ मैं (मैं टी के बारे में परवाह नहीं है) यह पता लगाने की यदि किसी विशेष प्रकार लागू करता IEnumerable<T> जरूरत है मैं कोड का एक टुकड़ा हैएफ # समकक्ष (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>> 
    ) 

पर ध्यान दिया लेकिन यह एक चेतावनी है कि 'ओबीजी की बाधा है। मैं यह नहीं जानना चाहता कि IEnumerable<obj> लागू किया गया है लेकिन IEnumerabl<> है।

किसी को भी पता है कि समाधान है और बीटीडब्ल्यू ऊपर दिए गए कोड पर भी टिप्पणी करने के लिए स्वतंत्र महसूस करता है।

+0

http://stackoverflow.com/questions/1652050/generic-type-definition- में पाए जाते हैं में से एक है बेपरवाह होगा वाक्यविन्यास-ऑन-एफ –

उत्तर

49

यह काम करना चाहिए:

typedefof<System.IEnumerable<_>> 

संपादित

टॉमस नोटों के रूप में, वहाँ _ वाइल्डकार्ड के बारे में यहाँ कुछ खास नहीं है; एफ # अनुमान लगाता है कि 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। यह सी # के दृष्टिकोण के विपरीत है, जो समान मामलों में पूरी तरह से ठीक काम करता है।

आपके कोड के अनुसार, मुझे लगता है कि आप कुछ अन्य बदलाव करना चाहते हैं, । भी, इस तरह सुनिश्चित करना है कि इंटरफेस GetGenericTypeDefinition कॉल करने से पहले सामान्य है के रूप में यहाँ कैसे मैं परीक्षण समारोह लिखने करेंगे:। जहाँ तक मुझे पता के रूप में

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

आपके समाधान ने मुझे दूसरी समस्या से बचाया :) इतना उपयोगी त्रुटि नहीं है "ऑब्जेक्ट के वर्तमान स्थिति के कारण असमर्थित" जो कहने का एक तरीका है, एक गैर सामान्य प्रकार –

17

, एफ # सी # के typeof(IEnumerable<>) के लिए किसी भी समतुल्य नहीं है यह वह जगह है क्योंकि, यह एक विशेष वाक्यविन्यास है जिसे स्पष्ट रूप से सी # द्वारा समर्थित किया गया है। एफ # में, typeof एक सामान्य कार्य है और प्रकार तर्क को पूरी तरह से निर्दिष्ट प्रकार होना चाहिए। आप एजी प्राप्त कर सकते हैं प्रोग्राम के इस तरह eneric प्रकार परिभाषा:

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

IEnumerable<'a> के साथ अपने समाधान के साथ समस्या यह है कि एफ # संकलक अभी भी उपयोग करने के लिए कुछ ठोस प्रकार खोजने के लिए की जरूरत है (के रूप में सामान्य प्रकार परिभाषा एक मान्य प्रकार नहीं है) है। यदि प्रकार अनुमान इस बात को कम करता है कि टाइप पैरामीटर किसी भी तरह से प्रतिबंधित नहीं है, तो यह डिफ़ॉल्ट प्रकार का उपयोग करता है, जो obj है।

संपादित करें मुझे typedefof<IEnumerable<_>> के बारे में पता नहीं था, यह बहुत उपयोगी है! वैसे भी, ध्यान दें कि अंडरस्कोर का कोई विशेष अर्थ नहीं है - वास्तविक प्रकार तर्क अभी भी IEnumerable<obj> है, लेकिन typedefof फ़ंक्शन दृश्य के पीछे GetGenericTypeDefinition पर कॉल करता है।

+0

धन्यवाद के लिए getgenerictypedefinition को कॉल नहीं कर सकता _ की स्पष्टीकरण –

संबंधित मुद्दे