2012-10-04 11 views
6

कहो मैं एक सार माता पिता वर्ग "पिता" कहा जाता है कि एक विधि "DisplayTitle" कहा जाता है को लागू करता है अधिलेखित करने से एक सी # उपवर्ग की रोकथाम। मैं इस विधि प्रत्येक उपवर्ग कि "पिता" विरासत के लिए एक ही रहना चाहता हूँ - मैं एक संकलन त्रुटि चाहते हैं, तो एक उपवर्ग अपने स्वयं के "DisplayTitle" विधि लागू करने के लिए प्रयास करता है। मैं इसे सी # में कैसे पूरा कर सकता हूं। मैं जावा में विश्वास करता हूं, मैं बस विधि को "अंतिम" के रूप में चिह्नित करता हूं, लेकिन मुझे सी # में कोई विकल्प नहीं दिख रहा है। मैं "मुहरबंद" और "ओवरराइड" के साथ घूम रहा हूं, लेकिन मुझे वह व्यवहार नहीं मिल रहा है जिसे मैं ढूंढ रहा हूं।एक विधि

उदाहरण के लिए, इस कोड में:

using System; 

namespace ConsoleApplication1 
{ 
    class Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Parent's Title"); } 
    } 

    class ChildSubclass : Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title"); 
    } 

    static void Main(string[] args) 
    { 
     ChildSubclass myChild = new ChildSubclass(); 
     myChild.DisplayTitle(); 
     Console.ReadLine(); 
    } 
    } 
} 

मैं कह रही है कि "ChildSubClass" "DisplayTitle" ओवरराइड नहीं कर सकते एक संकलन त्रुटि प्राप्त करना चाहते हैं। मुझे वर्तमान में एक चेतावनी मिलती है - लेकिन ऐसा लगता है कि ऐसा कुछ ऐसा है जो मुझे करने में सक्षम होना चाहिए और मुझे विधि लेबल करने के लिए उचित विशेषताओं को नहीं पता है।

उत्तर

10

मैं कैसे सी # में ऐसा कर सकते हैं। मैं जावा में विश्वास करता हूं, मैं बस विधि को "अंतिम" के रूप में चिह्नित करता हूं, लेकिन मुझे सी # में कोई विकल्प नहीं दिख रहा है।

किसी न किसी बराबर सी # में sealed है, लेकिन आप सामान्य रूप से केवल आभासी तरीकों के लिए इसकी आवश्यकता - और अपने DisplayTitle विधि आभासी नहीं है।

यह ध्यान रखें कि ChildSubclassहै नहीं अधिभावी DisplayTitle महत्वपूर्ण है - यह छिपा है। कोई भी कोड जो केवल Parent के संदर्भों का उपयोग करता है, उस कार्यान्वयन को कॉल करना समाप्त नहीं करेगा।

ध्यान दें कि साथ कोड के रूप में है, तो आप ChildSubclass में विधि के लिए new संशोधक जोड़ने के लिए आप को सलाह देने के एक संकलन समय चेतावनी मिलना चाहिए:

public new void DisplayTitle() { ... } 

आप कर सकते हैं नहीं रोक व्युत्पन्न वर्ग मौजूदा तरीकों, एक व्युत्पन्न वर्ग के निर्माण के लिए पूरी तरह से रोकने के लिए वर्ग ही सील बंद कर दिया के अलावा अन्य ... लेकिन कॉल जो व्युत्पन्न प्रकार सीधे का उपयोग नहीं करते परवाह नहीं करेंगे छुपा से।

क्या आपके असली चिंता यहाँ है? दुर्घटनाग्रस्त दुरुपयोग, या जानबूझकर समस्याएं?

संपादित करें: ध्यान दें कि आपके नमूना कोड के लिए चेतावनी हो सकता है कुछ की तरह:

Test.cs(12,19): warning CS0108: 
     'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited 
     member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword 
     if hiding was intended. 

मैं सुझाव है कि आप त्रुटियों में चेतावनी देते हैं, और फिर यह उनके :)

+1

मुझे लगता है कि मेरी असली चिंता आकस्मिक दुरुपयोग होगी। मेरे पास एक अन्य प्रोजेक्ट में एक अमूर्त वर्ग है जिसमें "टर्नऑन" और "टर्नऑफ" विधि है। विवरण में बहुत अधिक प्राप्त किए बिना - यह वर्ग असली दुनिया वस्तुओं का प्रतिनिधित्व करने के लिए कई बार उप-वर्ग होने जा रहा है। हालांकि, इन सभी उपकरणों को उसी तरह चालू और बंद कर दिया जाएगा। मैं सिर्फ खुद को या किसी और को अपने स्वयं के बंद करने/किसी भी प्रकार की चेतावनी के बिना अलग-अलग उपकरणों के लिए कमांड को चालू करने का प्रयास नहीं करना चाहता हूं। – user1720817

+0

@ user1720817: ठीक है * एक चेतावनी होगी *। मैं आपके नमूने कोड से चेतावनी को अपने उत्तर में संपादित करूंगा ... –

+0

हाँ, एक चेतावनी है :) यह सिर्फ मेरी ओसीडी है जो मुझे यह संकलन समय त्रुटि बनना चाहता है। इसे लिखने के लिए समय निकालने के लिए धन्यवाद! – user1720817

1

अपनी कक्षाओं, गुण, या तरीकों अधिभावी से उपवर्गों को रोकने के बंद संशोधक का उपयोग करें। जब आप मुहरबंद उपयोग करते हैं तो क्या काम नहीं कर रहा है?

http://msdn.microsoft.com/en-us/library/88c54tsw.aspx

+0

जब मैं उपयोग करता हूं: "सार्वजनिक मुहरबंद शून्य डिस्प्लेटाइटल() {कंसोल। राइटलाइन (" अभिभावक का शीर्षक ");}" मुझे संकलन त्रुटि मिलती है - "कंसोल अनुप्रयोग 1। अभिभावक। डिस्प्लेटाइट() 'को सील नहीं किया जा सकता क्योंकि यह नहीं है एक ओवरराइड "। – user1720817

2

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

एक व्युत्पन्न वर्ग को उसी नाम का उपयोग कर अपनी विधि को छुपा सकता है। यह शायद संकलन चेतावनी है जिसके बारे में आप बात कर रहे हैं। नया कीवर्ड का उपयोग चेतावनी को दबाता है। यह विधि किसी भी तरह से आपकी मूल विधि को ओवरराइड नहीं करती है, तो आपका बेस क्लास कोड हमेशा मूल विधि को कॉल करता है, न कि व्युत्पन्न कक्षा में से एक।

+0

+1 के लिए विशेष रूप से सी #/जावा अंतर के लिए ऐसा किया। –

0

मैं निश्चित रूप से निश्चित हूं कि आप जो चाहते हैं वह सी # में विधि संशोधक कीवर्ड का उपयोग करना संभव नहीं है।

मुहरबंद केवल एक पूर्वजों वर्ग में वर्चुअल विधि को ओवरराइड करते समय लागू होता है, जो और ओवरराइडिंग को रोकता है।

+0

अच्छा बिंदु, लेकिन ओपी कक्षाओं को विरासत में आधार विधि को छिपाने से रोकना चाहता है। यह सिर्फ संभव नहीं है। –

+0

मुझे लगता है कि यह मुझे सबसे ज्यादा भ्रमित करने का हिस्सा लगता है - मैं विरासत में प्राप्त एक विधि को क्यों सील कर सकता हूं, लेकिन इसे "बेस" कक्षा में नहीं कर सकता? – user1720817

+0

@ माइकल सैलमेन, मैंने कहा "आप जो चाहते हैं वह संभव नहीं है", आपका भ्रम कहां है? – Jace

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