2011-02-15 20 views
7

मैं एक जटिल प्रकार बनाने के लिए कोशिश कर रहा हूँ और निर्माण समय की जरूरत है, कुछ कार्रवाई करने के लिए। जब एक के लिए या एक काम से कुछ और संकलक पागल हो जाता है जगह करने की कोशिश करसमझौता एफ # प्रकार कंस्ट्रक्टर्स

type public MyType = 
    val private myvar: int 
    val private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = { 
     myvar = 1; 
     myvar2 = "Hello"; 
     (* Other assignments in the form var = val *) 
     (* Here I would like to start a cycle in order *) 
     for i in ctorpar.array do 
     (* Do something *) (* ERROR *) 
    } 

खैर: तो मैं अपने कोड लिखने शुरू कर दिया। मैं निम्नलिखित मान: नए वाक्य विन्यास की कम्प्यूटेशनल भाव एक, या बेहतर इस प्रकार है, नया एक कम्प्यूटेशनल अभिव्यक्ति है (मैं इस वजह कर्ली कोष्ठक और एक-दूसरे से एक oinstruction से अर्धविराम का मतलब)। और इस मामले में, कन्स्ट्रक्टर कम्प्यूटेशनल एक्सप्रेशन के लिए, केवल असाइनमेंट को पल करना संभव है।

इसलिए कृपया आप मुझे जवाब दे सकता है:

1) मेरी कटौती सही है? (computetional अभिव्यक्तियों और प्रकार के लिए कन्स्ट्रक्टर के संबंध में)।

2) मैं मैं निर्देशों का एक सेट व्यक्त निर्माता में निष्पादित करने के लिए जगह की जरूरत है कि क्या क्या करना चाहिए ???? खैर आप जानते हैं, कभी-कभी निर्माण समय पर कार्रवाई करने के लिए जरूरी है और इसमें चक्र से सबकुछ सभी संभावनाओं में शामिल हो सकता है।

लेकिन संकलक पागल वैसे भी हो जाता है ...

धन्यवाद KVD को मैं समझ गया कि मैं निम्न कार्य करने की संभावना है:

type public MyType = 
    val private myvar: int 
    val private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = 
     for i in ctorpar.ACollection do 
     (* Something *) 
     { 
     myvar = 1; 
     myvar2 = "Hello"; 
     } 

खैर मैं माफी चाहता हूँ, लेकिन यह मेरी मदद नहीं करता है क्योंकि एफ # संकलक मुझे यह बताता है:

वस्तु कंस्ट्रक्टर्स सीधे उपयोग की कोशिश नहीं कर सकते हैं/के साथ और कोशिश/अंत में पूर्व को वस्तु के प्रारंभ। यह जैसे 'में एक्स के लिए ...' कि इन निर्माणों का उपयोग करता है करने के लिए विस्तार से बता सकते हैं कंस्ट्रक्टर्स भी शामिल है। यह आम आईएल द्वारा लगाई गई सीमा है।

ठीक है, यदि समस्या कुछ वस्तु initalization करने से पहले क्या कर रही है, और यह सही लगता है, तो के करते हैं इस के बाद:

:

type public MyType = 
    val mutable private myvar: int 
    val mutable private myvar2: string 
    (* ...Some val declarations... *) 
    new() = { 
     (* The default ctor makes something *) 
    } 
    new (ctorpar: AnotherType) = 
     { 
     myvar = 1; 
     myvar2 = "Hello"; 
     } 
     then 
     for i in ctorpar.ACollection do 
     (* Something *) 
     myvar <- 10 

फिर विफलता से निराश मूल्य या कन्स्ट्रक्टर 'myvar' परिभाषित नहीं है।

मुझे क्या करना चाहिए ???? ऐसा लगता है कि, यह मेरी कक्षा में तत्वों को नहीं पहचानता है, यह सही लगता है क्योंकि इसे इंडेंटिफायर की आवश्यकता होती है जब सदस्यों को स्वयं या इस का उपयोग करते समय घोषित किया जाता है ... यहां इसका आत्म-संदर्भ नहीं है और, सही ढंग से, बताता है मैं: "आप कुछ पाने की कोशिश कर रहे हैं जो मैं आपको नहीं दे सकता !!!!!!"

उत्तर

13
  1. नहीं, आपकी अनुमान सही नहीं है। घुंघराले ब्रेसिज़ एक रिकॉर्ड निर्माण अभिव्यक्ति की तरह अधिक हैं, जिसमें केवल फ़ील्ड असाइनमेंट हो सकते हैं। आप ब्रेसिज़ के भीतर प्रत्येक क्षेत्र को मान निर्दिष्ट के अलावा और कुछ नहीं कर सकते।

  2. आप फील्ड असाइनमेंट (यानी, उद्घाटन ब्रेस से पहले) सामान्य से पहले बयान डाल सकते हैं। आप new (ctorpar:AnotherType) as this = ... और फिर this.myvar <- 10 उपयोग कर सकते हैं

    type public MyType = 
        val private myvar: int 
        val private myvar2: string 
    
        new() = 
        for i in 1 .. 10 do 
         printfn "Before field assignments %i" i 
        { myvar = 1; myvar2 = "test" } 
        then 
         for i in 1 .. 10 do 
         printfn "After field assignments %i" i 
    

संपादित

अपने नए सवाल के बारे में,: आप तो बाद में अन्य स्टेटमेंट्स को निष्पादित करना चाहते हैं, तो आप then कीवर्ड का उपयोग करने की जरूरत है।

+0

केवीबी आपको धन्यवाद, आप वास्तव में मुझे सबकुछ स्पष्ट करते हैं, न केवल मैंने जो कुछ पूछा है, बल्कि इससे भी ज्यादा। अब यह सेंस बनाता है। आपका बहुत बहुत धन्यवाद। – Andry

+0

"तब" कीवर्ड दस्तावेज़ में कहां दिखाई देता है? यह निश्चित रूप से काम करता है, लेकिन मुझे नहीं लगता कि मैंने इसे पहले कहीं भी देखा है। –

+1

@ रैमन - http://msdn.microsoft.com/en-us/library/dd233192.aspx के "कन्स्ट्रक्टर्स में निष्पादित साइड इफेक्ट्स" अनुभाग देखें। – kvb

9

केवीबी का उत्तर बढ़िया है और आपको वह सारी जानकारी देता है जो आपने पूछा :-)।

मैं सिर्फ अंतर्निहित वाक्यविन्यास का उपयोग करने की अनुशंसा करना चाहता हूं जहां प्राथमिक कन्स्ट्रक्टर तुरंत प्रकार के नाम के बाद लिखा गया है। इससे बहुत सी चीजें बहुत आसान हो जाती हैं:

type MyType(n:int, s:string) = 
    do 
    // Run before fields initialized (they aren't accessible here) 
    for i in 1 .. 10 do 
     printfn "Before field assignments %i" i 
    // Initialize fields (accessible from now on) 
    let myvar = n 
    let myvar2 = s 
    do // Run after fields initialized - you can use them here 
    for i in 1 .. 10 do 
     printfn "After field assignments %i" i 

    // You can add multiple constructors too: 
    new() = MyType(0, "hi") 
    member x.Foo = 0 
+2

दरअसल, यह भी देखें http://lorgonblog.wordpress.com/2009/02/13/the-basic-syntax-of-f-classes-interfaces-and-members/ – Brian

+0

सामान्य रूप से टॉमस पेट्रीसेक और @ केवीबी, आप दो सभी चीजों के साथ एक महान मदद F #। –

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