2010-12-27 25 views
44

मैं = ऑपरेटर पता अतिभारित नहीं किया जा सकता है, लेकिन क्या मैं यहाँ करना चाहते हैं के लिए एक रास्ता होना चाहिए:सी # में ओवरलोडिंग असाइनमेंट ऑपरेटर

मैं बस, क्लास बना रहा हूं मात्रात्मक इकाइयों का प्रतिनिधित्व करने के बाद से मैं मैं भौतिकी का थोड़ा सा कर रहा हूँ। जाहिर है, मैं सिर्फ एक आदिम से प्राप्त नहीं कर सकता, लेकिन मैं चाहता हूं कि मेरी कक्षाएं प्राइमेटिव्स की तरह व्यवहार करें - मैं बस उन्हें अलग-अलग टाइप करना चाहता हूं।

तो मैं जाने के लिए सक्षम होगा,

Velocity ms = 0; 
ms = 17.4; 
ms += 9.8; 

आदि

मैं ऐसा करने के तरीके यकीन नहीं है। मैं सोचा मैं सिर्फ इतना जैसे कुछ वर्गों लिखना चाहते हैं:

class Power 
{ 
    private Double Value { get; set; } 

    //operator overloads for +, -, /, *, =, etc 
} 

लेकिन जाहिरा तौर पर मैं असाइनमेंट ऑपरेटर को ओवरलोड नहीं कर सकते। क्या कोई तरीका है कि मैं इस व्यवहार को प्राप्त कर सकता हूं?

+0

क्या आपने एफ # की 'माप की इकाइयों' सुविधा को देखा है? यह एम (केजी और एम/एस जैसे मानक (आईएसओ) इकाइयों को जानता है, और यह इकाइयों के साथ भी गणना कर सकता है। –

+1

बिल्कुल, मैं अब इसका उपयोग कर रहा हूं। यह आईएसओ इकाइयों को नहीं जानता है, बल्कि आप इकाइयों को स्वयं परिभाषित करते हैं, जैसे '[] टाइप एम; नाव = 2.279069767' –

+1

क्षमा करें, मैं SI इकाइयों, जो 'माइक्रोसॉफ्ट में पूर्वनिर्धारित कर रहे हैं का कहना है कि करने के लिए होती: [] प्रकार s' और फिर तरह बातें उपयोग कर सकते हैं' एक = 9.8 /4.3 'जो पैदावार' वैल एक हैं। FSharp.Math.SI'। देखें: http://blogs.msdn.com/b/andrewkennedy/archive/2008/09/02/units-of-measure-in-f-part-two-unit-conversions.aspx –

उत्तर

67

ऐसा लगता है कि आप एक struct के बजाय एक वर्ग ... का उपयोग कर की तरह किया जाना चाहिए और फिर एक अंतर्निहित रूपांतरण ऑपरेटर बनाने, साथ ही इसके लिए विभिन्न ऑपरेटरों आदि

यहां कुछ नमूना कोड है:

public struct Velocity 
{ 
    private readonly double value; 

    public Velocity(double value) 
    { 
     this.value = value; 
    } 

    public static implicit operator Velocity(double value) 
    { 
     return new Velocity(value); 
    } 

    public static Velocity operator +(Velocity first, Velocity second) 
    { 
     return new Velocity(first.value + second.value); 
    } 

    public static Velocity operator -(Velocity first, Velocity second) 
    { 
     return new Velocity(first.value - second.value); 
    } 

    // TODO: Overload == and !=, implement IEquatable<T>, override 
    // Equals(object), GetHashCode and ToStrin 
} 

class Test 
{ 
    static void Main() 
    { 
     Velocity ms = 0; 
     ms = 17.4; 
     // The statement below will perform a conversion of 9.8 to Velocity, 
     // then call +(Velocity, Velocity) 
     ms += 9.8; 
    } 
} 

(अतिरिक्त नोट के रूप में ... मुझे नहीं कैसे यह वास्तव में एक वेग का प्रतिनिधित्व करता है, के रूप में निश्चित रूप से है कि एक दिशा की जरूरत है और साथ ही एक परिमाण के रूप में ।)

+3

बिल्कुल सही! धन्यवाद। इसके अलावा ... आप सही हैं। जाहिर है, मेरे भौतिकी प्रोफेसर पर्याप्त रूप से मेरे मस्तिष्क में वैक्टर को बाधित करने में नाकाम रहे :) –

+1

क्या कोई कारण नहीं है कि यह कक्षा नहीं हो सकता है? मैं 'स्लाररनीट' या 'वेक्टर यूनिट' वर्ग से उत्तराधिकारी होने की उम्मीद कर रहा था ताकि प्रत्येक इकाई के लिए _everything_ दोहराना न पड़े, और स्पष्ट रूप से structs –

+7

@ हेनक: नहीं, * गति * एक स्केलर का उत्तराधिकारी नहीं हो सकता है, लेकिन वेग की दिशा है। Http://en.wikipedia.org/wiki/Velocity देखें - "यह एक वेक्टर भौतिक मात्रा है; इसे परिभाषित करने के लिए परिमाण और दिशा दोनों की आवश्यकता होती है।" –

-9

मुझे लगता है कि इसे ओवरलोड नहीं किया जा सकता है क्योंकि सी # कक्षाएं ऑब्जेक्ट से ली गई हैं, इसलिए वे मूल रूप से ऑब्जेक्ट्स हैं, और जब आप असाइनमेंट ऑपरेटर का उपयोग करते हैं, तो आप मूल रूप से बस किसी अन्य ऑब्जेक्ट का संदर्भ दे रहे हैं। दूसरी तरफ, यदि आप संरचना का उपयोग करते हैं, तो आपको मूल रूप से सभी जानकारी की आवश्यकता होती है, इसलिए जब आप = ऑपरेटर का उपयोग करते हैं, तो सभी फ़ील्ड कॉपी किए जाएंगे।

तो मैं उसका सामना कहेंगे, और) एक समारोह कॉपी (बुलाया लागू करने और आप ठीक होना चाहिए :-)

+0

यह अन्य ऑपरेटरों से अलग कैसे है? आप दो ऑब्जेक्ट्स की सारी जानकारी एक साथ कैसे जोड़ते हैं? मैं पूरी ऑब्जेक्ट को सीधे लिखना चाहता हूं, पूरे ऑब्जेक्ट को ओवरराइट करने के बजाय –

+1

मुझे लगता है कि इसे ओवरलोड नहीं किया जा सकता क्योंकि भाषा डिजाइनरों ने सोचा कि यह एक बुरा विचार होगा।ऐसा कोई तकनीकी कारण नहीं है जो इसे नहीं किया जा सका। –

+1

नहीं, मुझे लगता है कि एक कारण है। मान लें कि आपके पास ऑब्जेक्ट है, और ऑब्जेक्ट बी है। एक बार जब आप कथन ए = बी चलाते हैं, तो ऑब्जेक्ट जिसे एक इच्छा द्वारा इंगित किया गया था वास्तव में कचरा इकट्ठा किया जाता है (क्योंकि अब कोई ऑब्जेक्ट इंगित नहीं करता है), तो यहां एक असाइनमेंट ऑपरेटर कैसे कार्यान्वित करेगा? दूसरी तरफ, अन्य सभी ऑपरेटर या तो एक और ऑब्जेक्ट (उदा। ए + बी) वापस करते हैं, या वास्तव में वर्तमान ऑब्जेक्ट को बदलते हैं जब यह खोने वाला नहीं होता है (यानी कचरा एकत्रित किया जाता है) (उदा। ए + = बी)। – Rafid

9

आप अंतर्निहित रूपांतरण ऑपरेटरों बना सकते हैं। एक अच्छा उदाहरण के साथ page on MSDN है।

उन्हें अपरिवर्तनीय structs बनाने के लिए भी एक अच्छा विचार है। यही वही है जो "प्राइमेटिव" हैं, और यही कारण है कि उनसे उत्तराधिकारी बनाना असंभव हो जाता है। आप एक संरचना चाहते हैं क्योंकि आप संदर्भ प्रकार अर्थशास्त्र के बजाय मूल्य-प्रकार अर्थशास्त्र चाहते हैं। और आप उन्हें अपरिवर्तनीय चाहते हैं, क्योंकि परिवर्तनशील मूल्य प्रकार आम तौर पर कर रहे हैं एक bad idea.

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