2009-05-20 16 views
15

मैंने अभी this page पर जानकारी पढ़ी है, और एक नया? ऑपरेटर का उल्लेख है, यह मेरे लिए काफी अस्पष्ट है कि इसका उपयोग क्या होगा।
क्या कोई भी त्वरित स्पष्टीकरण प्रदान कर सकता है, इस ऑपरेटर का उपयोग कैसे किया जाएगा और संभावित रूप से उपयोग केस का उल्लेख करने के लिए एक कोड छीनने के बाद?
संपादित करें: यह वास्तव में अजीब है, मैंने देखा है कि? डॉन के रिलीज नोट्स में ऑपरेटर का अब उल्लेख नहीं किया गया है। इसका कोई विचार क्यों है?एफ # ऑपरेटर "?"

उत्तर

30

दो नए "विशेष" इस एफ # विज्ञप्ति में ऑपरेटर, और कर रहे हैं (<? -) (?)। उन्हें परिभाषित नहीं किया गया है, लेकिन वे अधिभार के लिए उपलब्ध हैं, ताकि आप उन्हें स्वयं परिभाषित कर सकें। विशेष बात यह है कि वे अपने दूसरे ऑपरेंड का इलाज कैसे करते हैं: उन्हें एक वैध एफ # पहचानकर्ता होने की आवश्यकता होती है, लेकिन ऑपरेटर को स्ट्रिंग के रूप में कार्यान्वित करने के लिए इसे पास करने के लिए पास किया जाता है। दूसरे शब्दों में:

a?b 

को desugared है:

(?) a "b" 

और:

a?b <- c 

को desugared है:

(?<-) a "b" c 

उन ऑपरेटरों की एक बहुत ही सरल परिभाषा सकता है हो:

let inline (?) (obj: 'a) (propName: string) : 'b = 
    let propInfo = typeof<'a>.GetProperty(propName) 
    propInfo.GetValue(obj, null) :?> 'b 

let inline (?<-) (obj: 'a) (propName: string) (value: 'b) = 
    let propInfo = typeof<'a>.GetProperty(propName) 
    propInfo.SetValue(obj, value, null) 

ध्यान दें कि जब से gettor के लिए वापसी प्रकार सामान्य है, तो आप, ज्यादातर मामलों में उपयोग स्थल पर यह निर्दिष्ट करना होगा अर्थात्:

let name = foo?Name : string 

हालांकि आप कर सकते हैं अभी भी चेन कॉल (?) भी सामान्य है) (का पहला तर्क (के बाद से?):

:

let len = foo?Name?Length : int 

एक और अधिक दिलचस्प, कार्यान्वयन के लिए फिर से उपयोग CallByName वीबी द्वारा प्रदान की विधि है

इस बात का लाभ यह है कि यह दोनों गुण और खेतों सही ढंग से संभाल लेंगे,, IDispatch COM ऑब्जेक्ट के साथ काम आदि

+1

एक साइड नोट के रूप में, जाहिर है, एफ # पावरपैक में एक उचित डिफ़ॉल्ट कार्यान्वयन शामिल है। –

4

यह "?" जैसा लगता है ऑपरेटर डायनेमिक लैंग्वेज रनटाइम (डीएलआर) से संबंधित है। यही है, जब आप संकलन समय के बजाए रनटाइम पर ऑब्जेक्ट सदस्य (विधि, प्रॉपर्टी) से जुड़ना चाहते हैं तो आप इसका उपयोग करते हैं।

यह मजाकिया है क्योंकि मैं उम्मीद कर रहा था कि यह गतिशील सदस्य आमंत्रण सी # में भी कैसे काम करेगा। हां, सी # इस कार्यक्षमता को "छद्म" प्रकार ("गतिशील" आईआईआरसी) के माध्यम से उजागर करता है। मेरी राय में, यह कोड को कुछ हद तक कम स्पष्ट करता है (क्योंकि आपको यह जानने के लिए परिवर्तनीय घोषणा को ट्रैक करना होगा कि कॉल प्रारंभिक या देर से बाध्य है या नहीं)।

मुझे सटीक वाक्यविन्यास नहीं पता है, लेकिन अगर मुझे लगता है, तो यह या तो "।" को बदल देता है या बढ़ाता है। (डॉट) ऑपरेटर। में के रूप में:

let x = foo?Bar() 

या हो सकता है:

let x = foo.?Bar() 
+1

"क्योंकि आपको यह जानने के लिए परिवर्तनीय घोषणा को ट्रैक करना है कि कॉल प्रारंभिक या देर से बाध्य है या नहीं ..." आपको बहुत दूर ट्रैक करने की आवश्यकता नहीं है। गतिशील एक स्थानीय चर होना चाहिए और एक प्रकार का सदस्य नहीं हो सकता है; यदि आपको यह पता लगाने के लिए बहुत दूर स्क्रॉल करना है कि कोई चर गतिशील है या नहीं, तो आपको प्रतिबिंबित करने की आवश्यकता है। इसके अलावा यदि आप एक चर के नाम पर होवर करते हैं तो आईडीई खुशी से आपको बताएगा ... – Randolpho

+2

अच्छे अंक। इसके लायक होने के लिए, एक और कारण है कि मैं "गतिशील" प्रकार कार्यान्वयन पर "देर से बाध्य कॉल" ऑपरेटर पसंद करूंगा: यह देखते हुए कि एक इंटरफेस को लागू करके डीएलआर में हुक करना संभव है, मैं एक परिदृश्य की कल्पना कर सकता हूं आप उसी संदर्भ पर प्रारंभिक बाध्य कॉल और देर से बाध्य कॉल करना चाहते हैं। –

+0

जिज्ञासा से बाहर foo का प्रकार क्या होना चाहिए और मैं foo.Bar() के बजाय ऐसा क्यों करना चाहूंगा? इसके अलावा, क्या मैं पहले से ही प्रतिबिंब के माध्यम से एक ही परिणाम प्राप्त नहीं कर सकता? – em70

1

वहाँ एक मॉड्यूल FSharp.Interop.Dynamic है, nuget कि डीएलआर का उपयोग कर गतिशील ऑपरेटर को लागू करता है पर है।

let ex1 = ExpandoObject() in 
ex1?Test<-"Hi"; 
ex1?Test |> should equal "Hi"; 

यह ओपन सोर्स, अपाचे लाइसेंस, आप implementation देख सकते हैं और यह इकाई परीक्षण example cases शामिल है।