2010-05-25 11 views
5

क्यों ऐसा करते हैं:((System.Object) पी == नल)

// If parameter cannot be cast to Point return false. 
    TwoDPoint p = obj as TwoDPoint; 
    if ((System.Object)p == null) 
    { 
     return false; 
    } 
इसके बजाय इस बात का

:

// If parameter cannot be cast to Point return false. 
    TwoDPoint p = obj as TwoDPoint; 
    if (p == null) 
    { 
     return false; 
    } 

मुझे समझ नहीं आता क्यों आप कभी भी लिखना चाहते हैं ((सिस्टम .Object) पी)?

सादर,

दान

+1

आपको इसकी आवश्यकता नहीं है। – ChrisF

+1

मैं उसके लिए यह कहने का इंतजार कर रहा हूं कि उसके शिक्षक ने ऐसा करने के लिए कहा या कुछ :) – Earlz

+3

ठीक है लेकिन ... http://msdn.microsoft.com/en-us/library/ms173147(VS.80) .aspx –

उत्तर

12

आप object लिए डाली जब आप नहीं जानते या मूल वर्ग operator == अधिरोहित है कि क्या यकीन नहीं किया जा सकता:

using System; 
class AlwaysEqual 
{ 
    public static bool operator ==(AlwaysEqual a, AlwaysEqual b) 
    { 
     return true; 
    } 

    public static bool operator !=(AlwaysEqual a, AlwaysEqual b) 
    { 
     return true; 
    } 
} 


class Program 
{ 
    static void Main() 
    { 
     object o = new AlwaysEqual(); 
     AlwaysEqual ae = o as AlwaysEqual; 

     if (ae == null) 
     { 
      Console.WriteLine("ae is null"); 
     } 

     if ((object)ae == null) 
     { 
      Console.WriteLine("(object)ae is null"); 
     } 
    } 
} 

यह कोड आउटपुट केवल"ae is null", जो स्पष्ट रूप से मामला नहीं है। object पर कास्ट कक्षा operator == से बचाता है और इसलिए null के विरुद्ध एक वास्तविक संदर्भ जांच है।

+0

तो, (System.Object) को कास्टिंग ऑब्जेक्ट में "==" के आमंत्रण को मजबूर करेगा? अजीब .. – OscarRyz

+5

मैं हमेशा इन ऑब्जेक्ट्स में 'ऑब्जेक्ट। रेफरेंस एक्वाल्स (ओबीजे, नल)' वाक्यविन्यास पसंद करता हूं। यह कोड के इरादे को और अधिक स्पष्ट रूप से बताता है। – LukeH

+0

मुझे खींच लिया जा रहा है; लेकिन मुझे प्रश्न पूछना/शोध करना अच्छा लगेगा (जल्द ही कोशिश करें और फिर से दोहराएं) "जब एक विशेषज्ञ एमएसडीएन पाठ को सुधारता है तो क्या उन्हें और विस्तार करना चाहिए?"। अब, यह भरा हुआ है लेकिन मुझे जाना होगा ... –

1

स्पष्ट रूप से बोल, यह व्यर्थ है। नल को हमेशा निर्दिष्ट किया जा सकता है (बिना किसी नलिकाएं जैसे कि इंक और स्ट्रक्चर) को छोड़कर, ताकि इसे हमेशा चेक किया जा सके। कास्ट आवश्यक नहीं है

यदि TwoDPoint एक गैर-शून्य प्रकार है जैसे कि संरचना के रूप में वास्तव में यह एक बिंदु हो सकता है। (System.Object) कैश प्रभावी ढंग से संरचना को एक शून्य वस्तु में बॉक्स करेगा। लेकिन अगर ऐसा होता तो obj as TwoDPoint मान्य नहीं होगा। इसे हटाने के लिए आपको obj as TwoDPoint? की आवश्यकता होगी। (गैर-नलिकाओं के साथ उपयोग नहीं कर सकते)

+0

हम्म ठीक है। शायद यह बात है, गैर-नलिकाएं जो है। मैं इसे थोड़ा और देख लूंगा, धन्यवाद। यदि आपके पास समय है - http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx सम्मान, दान –

+0

@ डैनियल मेरे संपादन को देखते हैं कि यह गैर- शून्य समस्या हालांकि आपके लिंक के लिए। यह '==' ऑपरेटर की ओवरलोडिंग बहुत उत्सुक है। लेकिन 'बराबर' फ़ंक्शन स्थिर नहीं है, इसलिए यदि यह वैध ऑब्जेक्ट पर इंगित नहीं कर रहा है तो क्या होता है? यह सही सवाल है :) – Earlz

+0

@ Daniel मुझे लगता है कि @Mark इस पर सही है। – Earlz

1

.NET में प्रत्येक ऑब्जेक्ट सिस्टम से लिया गया है। ऑब्जेक्ट इसलिए स्पष्ट कलाकारों की आवश्यकता नहीं है।

+0

कूल - हाँ, मुझे थोड़ी देर लग गई; तुम सही हो, मैं देखता हूँ। धन्यवाद। Msdn http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx ने मुझे भ्रमित कर दिया। माफ़ कीजिये। –

1

और यहां तक ​​कि अधिक संक्षिप्त होगा:

if (!(obj is TwoDPoint)) { 
    return false; 
} 
+1

यदि आप केवल यह जांच रहे हैं कि 'पी' सही प्रकार का है तो यह अधिक कुशल होगा। – ChrisF

1

यह कोड पूरी तरह से समझता है अगर वह कोड Object.Equals ओवरराइड के अंदर है और आप समानता ऑपरेटर (जो उदाहरण के लिए, गलती से Equals पर कॉल करना चाहते हैं) का आह्वान नहीं करना चाहते हैं। ऑब्जेक्ट को कास्टिंग मानक समानता ऑपरेटर को कॉल करने की अनुमति देता है, जो संदर्भों की तुलना करता है।

आम तौर पर, आप Object.ReferenceEquals का उपयोग Equals ओवरराइड अंदर null को एक वस्तु का एक उदाहरण तुलना करने के लिए होगा।

उदाहरण के लिए, इस ढेर अतिप्रवाह कारण होगा:

public class Point { 
    public override bool Equals (object other) { 
    var otherPoint = other as Point; 

    if (other == null) 
     return false; 

    //... 
    } 

    public static bool operator == (Point l, Point r) { 
    //... 
    //null checks 
    if (!l.Equals(r)) 
     return false; 
    } 
} 

ऊपर के उदाहरण समानता ऑपरेटर में Equals कॉल करता है और क्योंकि otherPoint वैरिएबल प्रकार Point की है, यह समानता ऑपरेटर आह्वान होता है, अनंत प्रत्यावर्तन के कारण।

आम तौर पर, जब आप Equals ओवरराइड करते हैं और समानता ऑपरेटर को परिभाषित करते हैं, तो आप तुलनात्मक तर्क को ऑपरेटर में डाल देंगे और Equals ओवरराइड से इसका आह्वान करेंगे। ध्यान रखें कि कक्षा के लिए ओवरराइड होने पर वर्ग को अपरिवर्तनीय होने की अनुशंसा की जाती है।

public class Point { 
    public override bool Equals (object other) { 
    var otherPoint = other as Point; 
    return this == otherPoint; 
    } 

    //must override GetHashCode() as well 

    public static bool operator == (Point l, Point r) { 
    if (Object.ReferenceEquals(l, null) && Object.ReferenceEquals(r, null)) 
     return true; 
    if (Object.ReferenceEquals(l, null) || Object.ReferenceEquals(r, null)) 
     return false; 
    //actual equality checks 
    } 
    public static bool operator != (Point l, Point r) { 
    return !(l==r); 
    } 
} 
संबंधित मुद्दे