F #

2012-11-16 14 views
5

में टाइप एक्सटेंशन के रूप में अतिरिक्त विधियों को जोड़ना मेरे पास एक .Net लाइब्रेरी है जो पहले से ही .Item विधियों को कार्यान्वित कर चुकी है, उदाहरण के लिएF #

namespace Library2 
type A() = 
    member m.Item with get(a: string) = printfn "get a string" 
    member m.Item with get(a: int) = printfn "simple slice" 

कोड इस पुस्तकालय का उपयोग करता है में, मैं एक ही नाम के एक अतिरिक्त विधि जोड़ना चाहते हैं (इसलिए यह optional extensions है):

#r @"Library2.dll" 
open Library2 
type A with 
    member m.Item with get(a: bool) = 
     printfn "get a bool" 

निम्न उदाहरण की अंतिम पंक्ति संकलन नहीं है :

let a = new A() 
a.["good"]  
a.[10] 
a.[true] 

F# doc का कहना है:

एक्सटेंशन विधियां आभासी या अमूर्त विधियां नहीं हो सकती हैं। वे उसी नाम के अन्य विधियों को अधिभारित कर सकते हैं, लेकिन संकलक संदिग्ध कॉल के मामले में गैर-विस्तार विधियों की वरीयता देता है।

इसका मतलब है कि मैं उसी प्रकार के हस्ताक्षर के साथ .ToString/.GetHashCode का विस्तार नहीं कर सकता, लेकिन यहां मैं एक अलग प्रकार के हस्ताक्षर का उपयोग करता हूं। नई विधि क्यों नहीं बढ़ाया जा सकता है? ,

public static class MyModule 
{ 
    public static void Item(this A a, bool b) 
    { 
     // whatever 
    } 
} 

संकलक .Item(...) विधि की तलाश में है मूल Library2.A कक्षा में यह पाता है, और विफल रहता है:

+0

मुझे अजीब लगता है कि इंटेलिसेंस सभी तीन ओवरलोड दिखाता है। – Daniel

+0

हां। यह मुझे भ्रमित करता है ... –

उत्तर

0

मुझे लगता है, समस्या तथ्य विस्तार तरीके के रूप में निम्नलिखित (सी #) लागू किया जाता है के कारण होता है किसी भी विस्तार विधियों की तलाश करने के लिए।

ध्यान दें कि यदि सभी.Item(...) भार के विस्तार तरीके हैं, सब कुछ ठीक काम करता है:

module Library2 = 
    type A() = 
     member m.dummy =() 

open Library2 
type A with 
    member m.Item with get(a: string) = printfn "get a string" 
    member m.Item with get(a: int) = printfn "simple slice" 
    member m.Item with get(a: bool) = printfn "get a bool" 
+0

आंतरिक विस्तार और वैकल्पिक एक्सटेंशन के बीच अंतर है। मेरा मामला 'वैकल्पिक' है। –

+0

हां, आंतरिक एक्सटेंशन प्रकार में संकलित किए गए हैं, जैसे सी # में 'आंशिक' कक्षाओं की तरह। [वैकल्पिक विस्तार सदस्यों को स्थिर सदस्यों के लिए संकलित किया जाता है जिसके लिए ऑब्जेक्ट उदाहरण पहले पैरामीटर के रूप में निहित रूप से पारित किया जाता है।] (Http://msdn.microsoft.com/en-us/library/dd233211.aspx), और यह हो सकता है समस्या का कारण बनता है। – bytebuster

+0

यह ध्यान देने योग्य है: एफ # विस्तार गुणों का समर्थन करता है, लेकिन सी # नहीं करता है।तो वह क्या करने की कोशिश कर रहा है उसके लिए कोई सी # समकक्ष नहीं है। – Daniel

0

इस संकलक में एक बग हो रहा है। विस्तार विधि है और जब आप अच्छा वाक्यात्मक चीनी कि indexers के साथ आता है से बचना कहा जा सकता है, यानी यह काम करता है:

लाइब्रेरी:

namespace TestLibrary 

type A() = 
    member m.Item with get(a: string) = "string" 
    member m.Item with get(a: int) = "int" 

मुख्य:

open TestLibrary 

type A with 
    member m.Item with get(a: bool) = "bool" 

[<EntryPoint>] 
let main argv = 
    let a = new A() 
    printfn "%s" (a.get_Item "a") 
    printfn "%s" (a.get_Item 1) 
    printfn "%s" (a.get_Item true) 
    System.Console.ReadLine() |> ignore 
    0 

मेरी पहली अंतर्ज्ञान यह था कि एक इंडेक्सर के पास unit रिटर्न प्रकार के रूप में नहीं हो सकता है, लेकिन यह समस्या नहीं निकली।

0

अजीब, मैंने लिंककैड में भी इसी तरह की चीज बनाई और जैसा आपने अपेक्षा की थी।

module ModuleA = 

    type A() = 
     member m.Item with get(a: string) = printfn "get a string" 
     member m.Item with get(a: int) = printfn "simple slice" 

module ModuleB = 
    open ModuleA 

    type A with 
     member m.Item with get(a: bool) = printfn "get a bool" 

open ModuleB 

let a = new ModuleA.A() 
a.["good"]  
a.[10] 
a.[true] 

// get a string 
// simple slice 
// get a bool 
संबंधित मुद्दे

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