2017-02-21 15 views
19

परिचय बिना एकाधिक == ऑपरेटर भार के:
मैं कुछ वर्ग है जो एक ही काम करते हैं, लेकिन अलग अलग मूल्य प्रकार के साथ (तैरता या पूर्णांक जैसे वाहक)।
अब मैं समानता की जांच करने में सक्षम होना चाहता हूं, इस समानता को प्रकारों (जैसे वेक्टरएफ == वेक्टरआई) के बीच भी काम करना चाहिए।
इसके अलावा, यह एक शून्य जांच (vectorF == शून्य) करना संभव होना चाहिए।सी #, अस्पष्ट अशक्त जांच

दृष्टिकोण:
मेरे दृष्टिकोण == और के लिए कई भार के बनाने के लिए है = ऑपरेटरों, प्रत्येक संभव संयोजन के लिए एक!।

public sealed class VectorF 
{ 
    [...] 

    public static bool operator == (VectorF left, VectorI right) 
    { 
     // Implementation... 
    } 

    public static bool operator == (VectorF left, VectorF right) 
    { 
     // Implementation... 
    } 

    // Same for != operator 
    [...] 
} 

समस्या:
कई भार के का उपयोग करना, मैं सिर्फ == ऑपरेटर के साथ एक अशक्त जाँच नहीं कर सकते, के रूप में कॉल अस्पष्ट होगा।

var v = new VectorF([...]); 

if (v == null) // This call is ambiguous 
[...] 

मैं संभावना बजाय एक ReferenceEquals या नल कास्टिंग का उपयोग करने के बारे में पता कर रहा हूँ, लेकिन यह मेरे लिए एक गंभीर प्रतिबंध approachis।

var v = new VectorF([...]); 

if(object.ReferenceEquals(v, null)) // Would work, is not user friendly. 
[...] 

if(v == (VectorF)null) // Would also work, is neither user friendly. 
[...] 

प्रश्न:
वहाँ एक रास्ता में == ऑपरेटर लागू करने के लिए एक रास्ता है, यह आसान अशक्त जांच की अनुमति देता है कि, और विभिन्न वैक्टर के बीच समानता की जांच के लिए अनुमति देता है?

वैकल्पिक रूप से, क्या कोई और तरीका है कि मैं इसे कैसे कार्यान्वित कर सकता/सकती हूं?

+5

ऐसा लगता है कि आपके वेक्टर वर्ग वास्तव में अपरिवर्तनीय structs होना चाहिए। फिर 'शून्य' का मुद्दा नहीं उठता है। (मुझे लगता है कि आपकी कक्षाओं में केवल 2 या 3 मान हैं।) –

+2

लगता है जैसे [zugzwang] (https://en.wikipedia.org/wiki/Zugzwang): या तो अच्छी लग रही है '==' या '== शून्य '। अन्य प्रकार के वेक्टर के साथ तुलना करने के तरीकों के बारे में कैसे? जैसे 'VectorF।IsSame (वेक्टर I) '? जब वह 'vectorF == vectorI' की कोशिश करता है तो संकलक उपयोगकर्ता गलती दिखाएगा और फिर उपयोगकर्ता तुलना करने के तरीकों की खोज करेगा, tada, समस्या हल हो जाएगी? एक और बात: 'int' के साथ 'फ्लोट' की तुलना करना सटीक नहीं होगा, 'वेक्टर' को पहले 'वेक्टर I' में कास्टिंग करने के बारे में और फिर दो 'वेक्टर I' की तुलना कैसे करें? – Sinatr

+0

आपको बाएं-दाएं ओवरलोड की आवश्यकता क्यों है .. क्या आप हमें ओवरलोड विधियों की सामग्री साझा कर सकते हैं .. – levent

उत्तर

20

मैं पूरी डिजाइन के साथ शुरू करने के लिए वापस धक्का लगेगा। मैं == को विभिन्न प्रकारों के बीच मूल्य अर्थशास्त्र के साथ कभी भी लागू नहीं करूंगा, मुझे यह भ्रमित लगता है: instaceTypedA == instanceTypedB संदर्भ समानता (कम से कम मेरे लिए) yells।

यदि आपको काम करने की आवश्यकता है, तो VectorI और VectorF के बीच एक अंतर्निहित रूपांतरण लागू करें। इस तरह ढांचा काम करता है। आप निम्न कर जब:

int i = 1; 
double d = 1; 
var b = i == d; 

एक oveload ==(int, double) जादुई पैदा नहीं होता है। क्या होता है कि i को double और ==(double, double) में शामिल किया गया है।

+0

धन्यवाद। आप सही हैं, == संदर्भ समानता होना चाहिए। मैंने निहित रूपांतरण के बारे में नहीं सोचा था, क्योंकि मैं चाहता था कि कॉल जितना संभव हो सके अनुकूलित हो। हालांकि, जैसा कि मूल्यों को किसी भी रूप में परिवर्तित किया जाएगा, यह सब के बाद बहुत अंतर नहीं करता है। – Chillersanim

8

आप is का उपयोग करके तुलना घूम कर सकते हैं: अगर vnull है

if (v is VectorF) 

यह चेक असफल हो जायेगी।

+0

बहुत अच्छा है कि वास्तव में अच्छा समाधान है! –

+5

मुझे इस समाधान को काफी पसंद नहीं है। आप जो वास्तव में कर रहे हैं उसका अर्थशास्त्र "चालाक" चाल में छिपा हुआ है; इस कोड को पढ़ना, यह स्पष्ट है कि आप ईमानदार होने के लिए 'शून्य' की जांच कर रहे हैं। – InBetween

+1

ठीक है, 'is' (या' as') का उपयोग करके चेक टाइप करना काफी आम है, हालांकि सभी को यह नहीं पता कि यह शून्य जांच भी करता है। एक बार जब आप जानते हैं कि यह स्पष्ट है कि 'शून्य' एक विशिष्ट प्रकार का नहीं है। –

2

यह == ऑपरेटर को ओवरलोड मैं इस मामले में क्या होगा क्या नहीं करने के लिए, और बदले की तरह कुछ कार्य करें:

public static bool operator == (VectorF left, object right) { 
    if (object.ReferenceEquals(null, right)) { 
     // handle null case 
    } 
    VectorF rightF = right as VectorF; 
    if (!object.ReferenceEquals(null, rightF)) { 
     // Compare VectorF 
    } 
    VectorI rightI = right as VectorI; 
    if (!object.ReferenceEquals(null, rightI)) { 
     // Compare VectorI 
    } 
    // and so on... 
} 
+2

ईए, एक नल-चेक दोहराने के लिए संकलन-समय प्रकार की सुरक्षा का त्याग करना? –

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