2010-04-27 9 views
7

तो, तो कोडमैं कैसे Dictionary.TryGetValue रूप में एक ही व्यवहार लागू कर सकते हैं

type MyClass() = 
    let items = Dictionary<string,int>() 
    do 
    items.Add ("one",1) 
    items.Add ("two",2) 
    items.Add ("three",3) 
    member this.TryGetValue (key,value) = 
    items.TrygetValue (key,value) 
let c = MyClass() 

let d = Dictionary<string,int>() 
d.Add ("one",1) 
d.Add ("two",2) 
d.Add ("three",3) 

और निम्न परीक्षण कोड

let r1,v1 = d.TryGetValue "one" 
let r2,v2 = c.TryGetValue "one" 

r1 निम्नलिखित को देखते हुए v1 लाइन ठीक काम करता है। आर 2, वी 2 लाइन बम; शिकायत c.TryGetValue एक tuple दिया जाना चाहिए। दिलचस्प बात यह है कि प्रत्येक पंक्ति में TryGetValue का हस्ताक्षर अलग है। बीसीएल संस्करण के समान व्यवहार को प्रदर्शित करने के लिए मैं अपना कस्टम कार्यान्वयन कैसे प्राप्त कर सकता हूं? या, एक और तरीका पूछा, चूंकि एफ # (ट्यूपल पैरामीटर, करीबी पैरामीटर, और बीसीएल पैरामीटर की अवधारणा है), और मुझे पता है कि करीबी और ट्यूपल-स्टाइल के बीच अंतर कैसे करें, मैं तीसरी शैली को कैसे मजबूर कर सकता हूं (ला बीसीएल विधियों)?

अगर यह अस्पष्ट है तो मुझे बताएं।

उत्तर

8

TryGetValue एक बाहर पैरामीटर है, तो आप (एक byrefOutAttribute के साथ चिह्नित के माध्यम से) एफ # में भी ऐसा ही करने की जरूरत है:

open System.Runtime.InteropServices 
type MyDict<'K,'V when 'K : equality>() = // ' 
    let d = new System.Collections.Generic.Dictionary<'K,'V>() 
    member this.TryGetValue(k : 'K, [<Out>] v: byref<'V>) = 
     let ok, r = d.TryGetValue(k) 
     if ok then 
      v <- r 
     ok    

let d = new MyDict<string,int>() 
let ok, i = d.TryGetValue("hi") 
let mutable j = 0 
let ok2 = d.TryGetValue("hi", &j) 
स्वतः आप बदले मूल्यों में मानकों बाहर प्रत्यय बदलने देता है, तो आप

एफ # बस एक पैरामीटर में समाप्त होने वाली विधि को लिखने की आवश्यकता है।

+0

धन्यवाद। मैंने वास्तव में कोशिश की, लेकिन मुझे एहसास नहीं हुआ कि मुझे आउटएट्रिब्यूट की आवश्यकता है। मुझे लगता है कि byref <'v> पर्याप्त होगा। – pblasucci

+0

byref स्वयं ही सी # में 'रेफरी' जैसा है (जैसा कि सी # 'आउट' के विपरीत है)। – Brian

+2

आह, हाँ: रेफरी, बाहर ... बस मुझे किसी भी दिन tuples दे दो! – pblasucci

4

व्यक्तिगत रूप से, मुझे बीसीएल में उपयोग किए गए bool TryXXX(stringToParseOrKeyToLookup, out parsedInputOrLookupValue_DefaultIfParseFailsOrLookupNotFound) पैटर्न को कभी पसंद नहीं आया है। और जब एक tuple लौटने की एफ # चाल अच्छी है, शायद कभी भी अगर मुझे वास्तव में डिफ़ॉल्ट मान की आवश्यकता है तो एक पार्स या लुकअप विफल हो जाता है। दरअसल, Some/None पैटर्न (Seq.tryFind) की तरह अधिक उचित होगा:

type MyClass() = 
    let items = System.Collections.Generic.Dictionary<string,int>() 
    do 
    items.Add ("one",1) 
    items.Add ("two",2) 
    items.Add ("three",3) 
    member this.TryGetValue (key) = 
    match items.TryGetValue(key) with 
     | (true, v) -> Some(v) 
     | _ -> None 

let c = MyClass() 

let printKeyValue key = 
    match c.TryGetValue(key) with 
    | Some(value) -> printfn "key=%s, value=%i" key value 
    | None -> printfn "key=%s, value=None" key 

//> printKeyValue "three";; 
//key=three, value=3 
//val it : unit =() 
//> printKeyValue "four";; 
//key=four, value=None 
//val it : unit =() 
+0

टुपल से मेल खाने के लिए यहां 'मैच विद' का उपयोग करके शुद्ध कविता है। मेरे कोड में इस दृष्टिकोण का इस्तेमाल किया, बहुत अच्छा! धन्यवाद! – gjvdkamp

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