2010-03-25 11 views
20

में छाया बनाम अधिभार, जब हमारे पास new सी # में है, तो व्यक्तिगत रूप से मैं केवल उस संपत्ति को ओवरराइड करने के लिए एक वर्कअराउंड के रूप में देखता हूं जिसमें वर्चुअल/अतिरंजित घोषणा नहीं होती है, वीबी.नेट में हमारे पास दो "अवधारणाएं" Shadows हैं और Overloadsवीबीएनईटी

किस मामले में एक दूसरे को पसंद करते हैं?

उत्तर

13

तीन बारीकी से संबंधित अवधारणाएं हैं; ओवरराइडिंग, शेडिंग और ओवरलोडिंग।

ओवरराइड करना जब आप वर्चुअल विधि के लिए नया कार्यान्वयन करते हैं।

छायांकन तब होता है जब आप किसी विधि के लिए एक नया गैर-वर्चुअल कार्यान्वयन करते हैं।

ओवरलोडिंग तब होता है जब आप एक ही नाम के साथ एक विधि जोड़ते हैं लेकिन विभिन्न पैरामीटर।

सभी तीन अवधारणाएं सी # और वीबी दोनों में उपलब्ध हैं।

+1

सवाल ओवरराइडिंग के बारे में नहीं है, यह ठीक है। अब ** ओवरलोड ** का उपयोग ** शैडो ** मौजूदा सदस्य, या अधिभारित सदस्यों के सेट को बेस क्लास में भी किया जा सकता है। जब आप ओवरलोड का उपयोग इस तरह करते हैं, तो आप उसी नाम के साथ संपत्ति या विधि घोषित करते हैं और बेस क्लास सदस्य के समान तर्क सूची घोषित करते हैं, और आप छाया कीवर्ड की आपूर्ति नहीं करते हैं। मैं * नया * (सी #) = * छाया * (वीबीएनईटी) देखता हूं, सी # ओवरलोड के बराबर क्या है? – serhio

+0

@ सेरहियो: मैंने अभी पूर्णता के लिए ओवरराइडिंग का उल्लेख किया क्योंकि यह एक करीबी से संबंधित अवधारणा है। चूंकि VB में ओवरलोड कीवर्ड का उपयोग छायांकन के लिए भी किया जा सकता है, सी # में कोई सटीक समतुल्य नहीं है। सी # में ओवरलोडिंग के लिए कोई कीवर्ड नहीं है, आप बस उसी नाम के साथ एक विधि घोषित करें और इसे ओवरलोड करने के लिए अलग-अलग हस्ताक्षर दें। – Guffa

+1

इसलिए, आपकी परिभाषा पूरी नहीं हुई है, इसलिए ये 2 अवधारणाएं मेरे लिए अस्पष्ट नहीं हैं। 'छाया' एक "नया" फ़ंक्शन बनाता है, और उसी अधिभार के लिए 'ओवरलोड' का उपयोग किया जा सकता है। तो क्या अंतर है। – serhio

0

Shadows उन मामलों के लिए है जहां आपकी बेस क्लास Function SomeMethod() As String है और आप Function SomeMethod() As Integer चाहते हैं। मूल रूप से, वापसी प्रकार बदलने के लिए।

Overloads आपकी बेस क्लास Function SomeMethod() As String है और आप Function SomeMethod(ByVal value As Integer) As String जैसे पैरामीटर जोड़ना चाहते हैं।

+2

** अधिभार ** का उपयोग ** शैडो ** मौजूदा सदस्य, या अधिभारित सदस्यों के सेट को बेस क्लास में भी किया जा सकता है। जब आप ओवरलोड का उपयोग इस तरह करते हैं, तो आप उसी नाम के साथ संपत्ति या विधि घोषित करते हैं और बेस क्लास सदस्य के समान तर्क सूची घोषित करते हैं, और आप छाया कीवर्ड की आपूर्ति नहीं करते हैं। – serhio

16

मैं वास्तव में आधार वर्ग में एक समान नाम और हस्ताक्षर के साथ एक विधि के लिए Shadows बनाम Overloads के साथ एक ही कोड संकलन और दोनों के लिए ildasm से उत्पादन को देखकर पुष्टि की है। केवल अंतर Overloads केस hidebysig निर्दिष्ट करता है।

इसका महत्व जॉन स्कीट द्वारा this answer में सबसे अच्छा समझाया गया है।

लेकिन बस इसका मतलब है कि वहाँ केवल एक वास्तविक अंतर अगर आधार वर्ग नए सिरे से परिभाषित किया जा रहा विधि के भार के है: व्युत्पन्न वर्ग के माध्यम से

  • Shadows कारण उन सभी भार के की uncallable हो जाएगा , जहां
  • Overloads केवल एक विधि को प्रतिस्थापित करता है।

ध्यान दें कि यह केवल एक भाषा निर्माण है और सीएलआई द्वारा लागू नहीं है (यानी सी # और वीबी.नेट इसे लागू करते हैं लेकिन अन्य भाषाएं नहीं हो सकती हैं)।

एक साधारण कोड उदाहरण:

Module Module1 

Sub Main() 
    Dim a1 As C1 = New C2 
    Dim a2 As New C2 
    a1.M1() 
    a2.M1() 
    a1.M2() 
    a2.M2() 
    a1.M3() 
    a2.M3() 

    a1.M1(1) 
    ' Overloads on M1() allows the M1(int) to be inherited/called. 
    a2.M1(1) 
    a1.M2(1) 
    ' Shadows on M2() does not allow M2(int) to be called. 
    'a2.M2(1) 
    a1.M3(1) 
    ' Shadows on M3() does not allow M3(int) to be called, even though it is Overridable. 
    'a2.M3(1) 

    If Debugger.IsAttached Then _ 
     Console.ReadLine() 
End Sub 

End Module 

Class C1 
Public Sub M1() 
    Console.WriteLine("C1.M1") 
End Sub 
Public Sub M1(ByVal i As Integer) 
    Console.WriteLine("C1.M1(int)") 
End Sub 
Public Sub M2() 
    Console.WriteLine("C1.M2") 
End Sub 
Public Sub M2(ByVal i As Integer) 
    Console.WriteLine("C1.M2(int)") 
End Sub 
Public Overridable Sub M3() 
    Console.WriteLine("C1.M3") 
End Sub 
Public Overridable Sub M3(ByVal i As Integer) 
    Console.WriteLine("C1.M3(int)") 
End Sub 
End Class 

Class C2 
Inherits C1 
Public Overloads Sub M1() 
    Console.WriteLine("C2.M1") 
End Sub 
Public Shadows Sub M2() 
    Console.WriteLine("C2.M2") 
End Sub 
Public Shadows Sub M3() 
    Console.WriteLine("C2.M3") 
End Sub 
' At compile time the different errors below show the variation. 
' (Note these errors are the same irrespective of the ordering of the C2 methods.) 
' Error: 'Public Overrides Sub M1(i As Integer)' cannot override 'Public Sub M1(i As Integer)' because it is not declared 'Overridable'. 
'Public Overrides Sub M1(ByVal i As Integer) 
' Console.WriteLine("C2.M1(int)") 
'End Sub 
' Errors: sub 'M3' cannot be declared 'Overrides' because it does not override a sub in a base class. 
'   sub 'M3' must be declared 'Shadows' because another member with this name is declared 'Shadows'. 
'Public Overrides Sub M3(ByVal i As Integer) 
' Console.WriteLine("C2.M3(int)") 
'End Sub 
End Class 

ऊपर के उत्पादन:

C1.M1 
C2.M1 
C1.M2 
C2.M2 
C1.M3 
C2.M3 
C1.M1(int) 
C1.M1(int) 
C1.M2(int) 
C1.M3(int) 

उत्पादन से पता चलता Shadows कॉल जब C2 सीधे और नहीं जब C1 के माध्यम से परोक्ष रूप से कहा जाता है कहा जाता है उपयोग किया जाता है।