c# - सी#और एफ#लैम्ब्डा अभिव्यक्ति कोड पीढ़ी




serialization f# (2)

एफ #-जेनरेटेड क्लास क्यों सीलबंद के रूप में चिह्नित है?

क्योंकि संकलक नहीं करता है (यह कोड कोड पीढ़ी के अंत में है।

F #-जनरेटेड क्लास में सार्वजनिक फ़ील्ड क्यों हैं क्योंकि F # म्यूटेबल क्लोजर की अनुमति नहीं देता है?

आपको इसे संशोधित करने के लिए किसी उदाहरण के संदर्भ में पहुंचने में सक्षम होना चाहिए। लेकिन आप नहीं कर सकते हैं, इसलिए संशोधित होने से कोई फर्क नहीं पड़ता। और संभवतः यह विशेष मामले की आवश्यकता से बचाता है जहां बंद करने में एक उत्परिवर्तनीय कब्जा कर लिया जाता है।

एफ # जेनरेट क्लास में कन्स्ट्रक्टर क्यों है? यह सार्वजनिक क्षेत्रों के साथ पूरी तरह से शुरू किया जा सकता है ...

कोड कोड पसंद फिर से।

सी #-जेनरेटेड क्लास को [सीरियलज़ेबल] के रूप में चिह्नित क्यों नहीं किया जाता है? एफ # अनुक्रम अभिव्यक्तियों के लिए भी उत्पन्न कक्षाएं भी [सीरियलज़ेबल] बन गईं और सी # इटरेटर्स के लिए कक्षाएं नहीं हुईं।

अधिक कोड जनरेशन विकल्प।

इनमें से कोई भी विकल्प डेवलपर दृश्यमान नहीं है (यानी क्लाइंट कोड में कोई फर्क नहीं पड़ता) यह वास्तव में कोई फर्क नहीं पड़ता है।

चलिए सरल फंक्शन के लिए एफ # द्वारा उत्पन्न कोड को देखें:

let map_add valueToAdd xs =
    xs |> Seq.map (fun x -> x + valueToAdd)

लैम्ब्डा अभिव्यक्ति के लिए जेनरेट कोड (एफ # कार्यात्मक मान का उदाहरण) इस तरह दिखेगा:

[Serializable]
internal class [email protected] : FSharpFunc<int, int> {
    public int valueToAdd;
    internal [email protected](int valueToAdd) { this.valueToAdd = valueToAdd; }
    public override int Invoke(int x)  { return (x + this.valueToAdd); }
}

और लगभग उसी सी # कोड को देखें:

using System.Collections.Generic;
using System.Linq;

static class Program {
    static IEnumerable<int> SelectAdd(IEnumerable<int> source, int valueToAdd) {
        return source.Select(x => x + valueToAdd);
    }
}

और सी # लैम्ब्डा अभिव्यक्ति के लिए जेनरेट कोड:

[CompilerGenerated]
private sealed class <>c__DisplayClass1 {
    public int valueToAdd;
    public int <SelectAdd>b__0(int x) { return (x + this.valueToAdd); }
}

तो मेरे पास कुछ प्रश्न हैं:

  • एफ #-जेनरेटेड क्लास क्यों sealed के रूप में चिह्नित है?
  • F #-जनरेटेड क्लास में सार्वजनिक फ़ील्ड क्यों हैं क्योंकि F # म्यूटेबल क्लोजर की अनुमति नहीं देता है?
  • एफ # जेनरेट क्लास में कन्स्ट्रक्टर क्यों है? यह सार्वजनिक क्षेत्रों के साथ पूरी तरह से शुरू किया जा सकता है ...
  • सी #-जेनरेटेड क्लास को [Serializable] के रूप में चिह्नित क्यों नहीं किया जाता है? एफ # अनुक्रम अभिव्यक्तियों के लिए भी उत्पन्न कक्षाएं भी [Serializable] बन गईं और सी # इटरेटर्स के लिए कक्षाएं नहीं हुईं।

चूंकि वे कंपाइलर-जेनरेट किए गए हैं, इसलिए सीलबंद / सार्वजनिक क्षेत्र के मुद्दे थोड़ा सा म्यूट हैं - आपको डीबग टूल्स के अलावा इसे कभी नहीं देखना चाहिए - आप संकलक के चारों ओर कदम उठाने के अलावा इसे कैसे उपclassing या mutating करेंगे? यदि आपके पास डीबग एक्सेस का स्तर है तो आप वैसे भी इसे बदल सकते हैं (प्रतिबिंब के माध्यम से)।

सी # के लिए इसे कुछ ref / out उपयोग की अनुमति देने के लिए शीर्ष पर एक फ़ील्ड होना चाहिए, और कब्जे वाले उत्परिवर्तनीय structs (हाँ, बुराई, हम जानते हैं) के साथ सही उपयोग की अनुमति देने के लिए। मुझे लगता है कि एफ # यहां समान है (क्या आप कब्जे वाले मूल्य के उप-[उप- [उप-]] सदस्य को बदल सकते हैं?)। हालांकि, सदस्य शायद आंतरिक हो सकते हैं।

पुन [Serialziable] ; कुछ ऐसा जो बंद हो जाता है वह धारावाहिक हो सकता है? प्रतिनिधि बेहद खराब क्रमिक उम्मीदवार बनाते हैं। शायद एफ # की प्रकृति का मतलब है कि डिस्क पर एक ऑपरेशन (मध्य प्रवाह) को बनाए रखने के लिए यह बेहतर अनुकूल है - लेकिन आम तौर पर, मैं इसकी अनुशंसा नहीं करता। मुझे इन ऑब्जेक्ट्स (इटरेटर और कैप्चर-क्लासेस) की धारावाहिक होने की कोई उम्मीद नहीं होगी।







lambda