डाउनकास्ट और upcast


88

मैं C # (और OOP ) के लिए नया हूं । जब मेरे पास निम्नलिखित जैसे कुछ कोड हों:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

प्रश्न 1 : यदि मेरे पास अन्य कोड है जो यह करता है:

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

यहाँ Employeeएक है Manager, लेकिन जब मैंने इसे इस तरह कास्ट किया तो एEmployee तो इसका मतलब है कि मैं इसे बढ़ा रहा हूं?

प्रश्न 2 :

जब मेरे पास कई Employeeश्रेणी की वस्तुएं हैं और कुछ नहीं, लेकिन उनमें से सभी नहीं हैं Manager, तो मैं उन्हें कैसे नीचे गिरा सकता हूं?


6
सुस्पष्ट कलाकारों के बिना अपकास्टिंग किया जा सकता है। तो Employee emp= mgr;पर्याप्त होना चाहिए।
मेरी बगल चुंबन

जवाबों:


93
  1. वह सही है। जब आप ऐसा करते हैं कि आप इसे एक employeeऑब्जेक्ट में डाल रहे हैं , तो इसका मतलब है कि आप कुछ भी विशिष्ट प्रबंधक तक नहीं पहुंच सकते।

  2. डाउनकास्टिंग वह जगह है जहाँ आप एक बेस क्लास लेते हैं और फिर इसे और अधिक विशिष्ट वर्ग में बदलने की कोशिश करते हैं। इसका उपयोग करके पूरा किया जा सकता है और इस तरह से एक स्पष्ट डाली है:

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

या asइस तरह ऑपरेटर के साथ :

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

अगर कुछ भी स्पष्ट नहीं है, तो मुझे इसे सुधारने में खुशी होगी!


मुझे यह जानने के लिए उदाहरण की आवश्यकता है कि डाउनकास्टिंग क्या है?
user184805

4
अच्छी तरह से स्थापित शब्दों को फिर से परिभाषित करने से बचें: "बॉक्सिंग", ओओपी और सी # के संदर्भ में, का मतलब कुछ अलग है (एक संदर्भ में मूल्य प्रकार ऑब्जेक्ट लपेटकर)। इसके अलावा, आपका उदाहरण (और चाहिए) के asबजाय ऑपरेटर का उपयोग कर सकता है is, एक कलाकार द्वारा पीछा किया।
कोनराड रुडोल्फ

2
मैं पहले बिंदु पर सही हुआ, और मैंने अपने उत्तर के दूसरे भाग को बदल कर दोनों करने के तरीके बताए।
RCIX

2
आपका पहला बयान ("... कास्टिंग" एक प्रबंधक वर्ग का उदाहरण "एक" कर्मचारी "ऑब्जेक्ट [..] में है, जिसका अर्थ है कि आप कुछ भी प्रबंधक तक नहीं पहुंच सकते हैं") पूरी तरह से सही नहीं है। ओपी के उदाहरण में, यदि कर्मचारी के पास एक आभासी सदस्य है जो प्रबंधक में ओवरराइड है, सीएलआर प्रबंधक कार्यान्वयन को कॉल करेगा, भले ही कलाकारों के बावजूद। C # में बहुरूपता पर MSDN लेख से: "जब एक व्युत्पन्न वर्ग एक आभासी सदस्य से आगे निकल जाता है, तो उस सदस्य को तब भी बुलाया जाता है, जब उस वर्ग का एक उदाहरण आधार वर्ग के उदाहरण के रूप में एक्सेस किया जा रहा हो।" MSDN द्वारा प्रदान किया गया उदाहरण लगभग समान है।
एंटनी

49

अपकास्टिंग (उपयोग करना (Employee)someInstance) आम तौर पर आसान होता है क्योंकि संकलक आपको संकलन समय पर बता सकता है यदि एक प्रकार दूसरे से लिया गया है।

हालांकि डाउनकास्टिंग को आमतौर पर रन टाइम पर करना पड़ता है क्योंकि कंपाइलर को हमेशा पता नहीं चलता है कि प्रश्न में दिया गया उदाहरण किस प्रकार का है। सी # इस के लिए दो ऑपरेटरों प्रदान करता है - है जो आप अगर खिन्न काम करता है बताता है, और सही / गलत लौट आते हैं। और के रूप में जो प्रयास डाली करते हैं और सही प्रकार यदि संभव हो तो, या अशक्त नहीं तो रिटर्न के लिए।

यह जांचने के लिए कि क्या एक कर्मचारी एक प्रबंधक है:

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

आप भी इसका इस्तेमाल कर सकते हैं

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");

11
  • Upcasting एक ऑपरेशन है जो एक उपवर्ग संदर्भ से एक बेस क्लास संदर्भ बनाता है। (उपवर्ग -> सुपरक्लास) (अर्थात प्रबंधक -> कर्मचारी)
  • डाउनकास्टिंग एक ऑपरेशन है जो एक बेस क्लास संदर्भ से एक उपवर्ग संदर्भ बनाता है। (सुपरक्लास -> उपवर्ग) (यानी कर्मचारी -> प्रबंधक)

आपके मामले में

Employee emp = (Employee)mgr; //mgr is Manager

आप एक उत्थान कर रहे हैं।

एक upcast हमेशा एक डाउनकास्ट के विपरीत सफल होता है जिसे एक स्पष्ट कलाकारों की आवश्यकता होती है क्योंकि यह रनटाइम में संभावित रूप से विफल हो सकता है। ( InvalidCastException )।

इस अपवाद से बचने के लिए C # दो ऑपरेटर प्रदान करता है:

से शुरू:

Employee e = new Employee();

प्रथम:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

दूसरा:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

चेतावनी : जब आप एक upcast करते हैं तो आप केवल सुपरक्लास के तरीकों, गुणों आदि तक पहुंच सकते हैं ...


6

मामले में आपको कर्मचारी की प्रत्येक वस्तु की जाँच करने की आवश्यकता है, चाहे वह प्रबंधक वस्तु हो, theType विधि का उपयोग करें:

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}

2

उत्तर 1: हाँ, इसे अपकास्टिंग कहा जाता है लेकिन जिस तरह से आप इसे करते हैं वह आधुनिक तरीका नहीं है। Upcasting अंतर्निहित रूप से किया जा सकता है आपको किसी भी रूपांतरण की आवश्यकता नहीं है। तो बस कर्मचारी साम्राज्य = mgr लिखना ; ऊपर उठने के लिए पर्याप्त है।

उत्तर 2: यदि आप प्रबंधक वर्ग की वस्तु बनाते हैं तो हम कह सकते हैं कि प्रबंधक एक कर्मचारी है। क्योंकि क्लास मैनेजर: एम्प्लॉई क्लास और मैनेजर क्लास के बीच इ -ए संबंध को दर्शाता है । इसलिए हम कह सकते हैं कि प्रत्येक प्रबंधक एक कर्मचारी है।

लेकिन अगर हम कर्मचारी वर्ग की वस्तु बनाते हैं तो हम यह नहीं कह सकते कि यह कर्मचारी प्रबंधक है क्योंकि वर्ग कर्मचारी एक ऐसा वर्ग है जो किसी अन्य वर्ग को विरासत में नहीं मिला है। तो आप सीधे उस क्लास क्लास ऑब्जेक्ट को मैनेजर क्लास ऑब्जेक्ट पर डाउनकास्ट नहीं कर सकते।

तो जवाब है, यदि आप कर्मचारी वर्ग वस्तु से प्रबंधक वर्ग वस्तु तक डाउनकास्ट करना चाहते हैं, तो पहले आपके पास प्रबंधक वर्ग की वस्तु होनी चाहिए, फिर आप इसे बढ़ा सकते हैं और फिर आप इसे नीचे कर सकते हैं।


-1

अपकास्टिंग और डाउनकास्टिंग:

Upcasting: Derived-Class से Base Class डाउनकास्टिंग तक कास्टिंग: Base Class से Derived Class तक कास्टिंग

आइए इसे एक उदाहरण के रूप में समझते हैं:

दो वर्गों के आकार को मेरा मूल वर्ग मानें और एक व्युत्पन्न वर्ग के रूप में सर्किल, निम्नानुसार परिभाषित किया गया है:

class Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
}

class Circle : Shape
{
    public int Radius { get; set; }
    public bool FillColor { get; set; }
}

upcasting:

आकार s = नया आकार ();

वृत्त c = s;

दोनों c और s एक ही मेमोरी लोकेशन को संदर्भित कर रहे हैं, लेकिन दोनों के अलग-अलग विचार हैं, अर्थात "c" संदर्भ का उपयोग करके आप बेस क्लास और व्युत्पन्न वर्ग के सभी गुणों का उपयोग कर सकते हैं, लेकिन "s" संदर्भ का उपयोग करके आप गुणों तक पहुँच सकते हैं एकमात्र अभिभावक वर्ग का।

अपकास्टिंग का एक व्यावहारिक उदाहरण स्ट्रीम क्लास है जो कि सभी प्रकार के स्ट्रीम रीडर की मूल रूपरेखा है। नेट फ्रेमवर्क:

स्ट्रीमराइडर रीडर = नया स्ट्रीमराइडर (नया फाइलस्ट्रीमरडर ());

यहाँ, FileStreamReader () स्ट्रेडम रेडर के लिए अपस्टेड है।

downcasting:

आकार एस = नया सर्कल (); जैसा कि ऊपर बताया गया है, s का दृश्य एकमात्र माता-पिता है, इसे माता-पिता और बच्चे दोनों के लिए बनाने के लिए हमें इसे नीचे करना होगा

var c = (Circle) s;

डाउनकास्टिंग का व्यावहारिक उदाहरण WPF का बटन वर्ग है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.