2010-12-02 16 views
9

मान लीजिए सील करने के लिए मैं इस तरह स्पष्ट रूप से काल्पनिक सी # वर्गों की एक जोड़ी है:कैसे एक अधिरोहित संपत्ति

public abstract class Foo { 
    public abstract int[] LegalValues { get; } 
    public virtual bool IsValueLegal(int val) { 
     return Array.IndexOf(LegalValues, val) >= 0; 
    } 
} 

और इस:

मैं एफ # में ऐसा कैसे करते हैं? गुणों के लिए स्पष्ट कोड:

[<Sealed>] 
override this.LegalValues with get() = // ... 

[<Sealed>] 
override this.IsValueLegal value = // ... 

एक त्रुटि ट्रिगर करता है क्योंकि SealedAttribute स्पष्ट रूप से सदस्यों पर लागू नहीं किया जा सकता है। मैं निश्चित रूप से, पूरे वर्ग को सील कर सकता हूं और इस प्रकार सभी सदस्यों को सील कर सकता हूं, लेकिन (और यह वास्तव में महत्वपूर्ण है) लेकिन यह है कि मेरे पास मौजूदा वर्ग हस्ताक्षर से बिल्कुल मिलान करने का लक्ष्य है और बेस क्लास में अन्य है आभासी/अमूर्त सदस्य जो आदर्श रूप से अतिसंवेदनशील रहना चाहिए।

+1

एचएम, मुझे यह भी पता नहीं था कि सी #/सीएलआर में अलग-अलग तरीकों को सील करना संभव था! – Brian

उत्तर

3

वर्तमान में ओओ के लिए एफ # के समर्थन के लिए कई सीमाएं हैं, इसलिए आपको आम तौर पर एफ # कक्षा पदानुक्रम का उत्पादन करने में सक्षम होने की उम्मीद नहीं करनी चाहिए जो कि मनमाना सी # कक्षा पदानुक्रम के समान है। जहां तक ​​मुझे पता है, वर्चुअल विधि को ओवरराइड और सील करने का कोई तरीका नहीं है।

5

ऐसा लगता है कि F # Sealed Attribute को परिभाषित करता है, इसकी विशेषता ट्रेडमार्क संपत्ति केवल कक्षा में सेट की गई है, संभवतः सदस्यों को सील करना संभव नहीं है।

यह शायद ठीक है, क्योंकि विरासत और ओवरराइडिंग फ़ंक्शन आमतौर पर सी # से F # में कम मूर्खतापूर्ण होते हैं। मुझे नहीं लगता कि आप वास्तव में एफ # मुहावरे में फिर से लिखने के बिना जो चाहते हैं उसे प्राप्त कर सकते हैं। इस से शुरू करें:

type foo = 
    | Bar 
    | Baz 
    | Qux 
     with 
      member this.LegalValues = 
       match this with 
       | Bar -> [0; 1] 
       | Qux -> [-1; 0; 1] 
       | Baz -> [0 .. 10 ] 
      member this.IsValueLegal value = 
       match this with 
       | Baz -> value >= 0 && value <= 10 
       | _ -> List.exists (fun x -> x = value) (this.LegalValues) 

आप कह सकते हैं कि Baz 'ओवरराइड "foo.IsValueLegal सदस्य, अन्य सभी प्रकार के" आधार "समारोह का उपयोग करें।

+0

दिलचस्प दृष्टिकोण, लेकिन मैं इसका उपयोग नहीं कर सकता - बेस क्लास किसी विशेष विरासत को परिभाषित करता है, इसलिए मैं किसी भी परिस्थिति में फू को फिर से परिभाषित नहीं कर सकता हूं और मुझे इन तरीकों को ओवरराइड करने से रोकने के लिए बार में आवश्यक है। अगर मुझे पूरी कक्षा को सील करना है, तो ऐसा ही हो। हालांकि यह कुछ परिचालनों को काट देगा, उन्हें अन्य तरीकों से अनुकरण किया जा सकता है (एडेप्टर, आदि)। – plinth