2011-09-07 17 views
6

पदानुक्रम मैं निम्नलिखित कोड है:एफ # भेदभाव यूनियनों

public abstract class A ... 
public class B : A ... 
public class C : A ... 

void my_fct(A x) { 
    if (x is B) { block_1 } 
    else if (x is C) { block_2 } 
    else { block_3 } 
} 

और मुझे आश्चर्य है कि अगर यह एफ #

type a = B | C 
let my_fct x = 
    match x with 
    | B -> (block_1) 
    | C -> (block_2) 
    | _ -> (block_3) 

से एक अच्छा अनुवाद है ??

+0

मुझे लगता है कि यह ठीक है। सिवाय इसके कि आप गायब हैं; block_1 के बाद, block_2 और block_3 –

+2

मेरी अज्ञानता क्षमा करें, लेकिन ऐसा लगता है कि 'block_3' को कभी भी F # स्निपेट में निष्पादित नहीं किया जा सकता है (बीजगणितीय डेटा प्रकार "बंद" हैं जहां तक ​​मुझे पता है), तो यह क्यों है? साथ ही, क्या मैं अकेला सोच रहा हूं कि अनुवाद में बहुरूपता का उपयोग करना चाहिए? – delnan

+0

आप ब्लॉक_3 के बारे में पूरी तरह से सही हैं। – Hugo

उत्तर

11

एफ # भेदभाव वाले संघ ओओ कक्षा पदानुक्रमों से काफी निकटता से मेल खाते हैं, इसलिए यह शायद सबसे अच्छा विकल्प है। सबसे उल्लेखनीय अंतर यह है कि आप प्रकार के घोषणापत्र को संशोधित किए बिना भेदभाव वाले संघ में नए मामले नहीं जोड़ सकते हैं। दूसरी ओर, आप आसानी से नए कार्यों को जोड़ सकते हैं जो प्रकार के साथ काम करते हैं (जो मोटे तौर पर सी # में नए आभासी तरीकों को जोड़ने के अनुरूप है)।

तो, यदि आप नई विरासत कक्षाओं (मामलों) को जोड़ने की उम्मीद नहीं करते हैं, तो यह सबसे अच्छा विकल्प है। अन्यथा, आप F # ऑब्जेक्ट प्रकार (या परिदृश्य के आधार पर अन्य विकल्प) का उपयोग कर सकते हैं। अपने कोड के बारे में

एक और बिंदु - जब से तुम नए मामले सामने नहीं जोड़ सकते, एफ # संकलक जानता है कि केवल मामलों की जरूरत B और C के लिए कर रहे हैं। नतीजतन, block_3 कभी नहीं मार डाला जा सकता है, जिसका अर्थ है कि आप बस लिख सकते हैं:

let my_fct x = 
    match x with 
    | B -> (block_1) 
    | C -> (block_2) 
7

हाँ यह और अधिक या कम एक ही एफ # किसी भी तरह से करता है के रूप में है। इस मामले में (कोई मूल्य जोड़ा नहीं गया) - F # इसे "ए" और कुछ टैग (गणना) के लिए कक्षाओं में अनुवादित करता है। "एक" सिर्फ बी और सी के लिए कुछ स्थिर गुण, और कुछ तरीकों है के लिए वर्ग की जाँच करने के लिए यदि प्रकार का ऑब्जेक्ट "एक" "बी" या "सी" है (नीचे देखें)

Object-Browser of the types

लेकिन आपको "_ -> (block_3)" मामले की आवश्यकता नहीं है, क्योंकि यह कभी मेल नहीं खाया जा सकता है (एफ # सभी संभावित मामलों को जानता है और आपको चेतावनी देगा)।

मुझे लगता है कि अगर आप इस "अन्य" मामले के लिए सी # में अपवाद फेंकते हैं तो बेहतर होगा।

+0

अच्छी तरह से मुझे लगता है कि टॉमस ने इसे अच्छा लगा;) – Carsten

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