सी # में बेस कन्स्ट्रक्टर को कॉल करना

यदि मैं बेस क्लास से उत्तराधिकारी हूं और विरासत वर्ग के निर्माता से बेस क्लास के निर्माता को कुछ पास करना चाहता हूं, तो मैं यह कैसे कर सकता हूं?

उदाहरण के लिए,

अगर मैं अपवाद वर्ग से उत्तराधिकारी हूं तो मैं ऐसा कुछ करना चाहता हूं:

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     {
         //This is where it's all falling apart
         base(message);
     }
}

असल में जो मैं चाहता हूं वह बेस अपवाद वर्ग को स्ट्रिंग संदेश पास करने में सक्षम होना है।

0
ro fr bn
यह भी ध्यान देने योग्य है कि आप यह base के लिए यह को प्रतिस्थापित करके अपने वर्तमान वर्ग में चेन कन्स्ट्रक्टर कर सकते हैं।
जोड़ा लेखक Quibblesome, स्रोत

10 उत्तर

अपने कन्स्ट्रक्टर को निम्न में संशोधित करें ताकि वह बेस क्लास कन्स्ट्रक्टर को सही तरीके से कॉल कर सके:

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}

ध्यान दें कि एक कन्स्ट्रक्टर ऐसा कुछ नहीं है जिसे आप किसी विधि के भीतर कभी भी कॉल कर सकते हैं। यही कारण है कि आपको कन्स्ट्रक्टर बॉडी में आपकी कॉल में त्रुटियां मिल रही हैं।

0
जोड़ा
यदि आपको ओवरराइड के बीच में बेस कन्स्ट्रक्टर को कॉल करने की आवश्यकता है, तो उसे बेस क्लास पर एक वास्तविक विधि में निकालें जिसे आप स्पष्ट रूप से कॉल कर सकते हैं। बेस कन्स्ट्रक्टर के साथ धारणा यह है कि वे सुरक्षित रूप से ऑब्जेक्ट बनाने के लिए बिल्कुल जरूरी हैं, इसलिए आधार को हमेशा पहले कहा जाएगा।
जोड़ा लेखक Jon Limjap, स्रोत
@ सेबेस्टियन हां और नहीं। यदि आपका कन्स्ट्रक्टर अन्य आदिम संचालन (सार विधियों) को बुलाते हुए आपकी टेम्पलेट विधि के रूप में कार्य करता है तो इसे कार्यान्वित करना संभव है। एक अन्य विधि या किसी अन्य कन्स्ट्रक्टर ओवरराइड से स्पष्ट रूप से एक कन्स्ट्रक्टर को कॉल करने की आवश्यकता वाले किसी अन्य कार्यान्वयन को प्रतिबंधित किया गया है।
जोड़ा लेखक Jon Limjap, स्रोत
यह है बस एक विधि जिसे आप किसी भी समय कॉल कर सकते हैं, आईएल-वार। सी # बस इसके शीर्ष पर अतिरिक्त प्रतिबंध लगाने के लिए होता है।
जोड़ा लेखक Roman Starkov, स्रोत
यह ध्यान देने योग्य है कि base कन्स्ट्रक्टर को पहले विधि ब्लॉक तक पहुंचाया जाता है। msdn.microsoft.com/en-us/library/ms173115.aspx
जोड़ा लेखक John Weisz, स्रोत
यदि आपको अपने कन्स्ट्रक्टर के दौरान बेस क्लास कन्स्ट्रक्टर मिडवे को कॉल करने की आवश्यकता है तो यह एक अच्छा डिज़ाइन नहीं है। एक कन्स्ट्रक्टर का विचार यह है कि यह अपने काम को करने के लिए आवश्यक सभी काम करता है। इसका प्रभाव यह है कि जब आपका व्युत्पन्न कन्स्ट्रक्टर शुरू होता है, तो बेस क्लास पहले ही पूरी तरह से प्रारंभ हो चुका है और व्युत्पन्न कक्षा किसी भी बेस क्लास फ़ंक्शन को कॉल करने के लिए स्वतंत्र है। यदि आपका डिज़ाइन ऐसा है कि आप अपने कन्स्ट्रक्टर के आधे रास्ते से कुछ करना चाहते हैं, तो स्पष्ट रूप से यह बेस क्लास ans प्रारंभ नहीं कर रहा है, इस प्रकार बेस क्लास के कन्स्ट्रक्टर में नहीं होना च
जोड़ा लेखक Harald Coppoolse, स्रोत
मुझे लगता है कि आप इस बिंदु को याद कर सकते हैं। समस्या अतिव्यापी कन्स्ट्रक्टर के माध्यम से बेस कंस्ट्रक्टर मिडवे को कॉल करने के बारे में थी। शायद बेस कन्स्ट्रक्टर का डेटा-प्रकार समान नहीं है या आप श्रृंखला को पार करने से पहले कुछ डेटा मोल्डिंग करना चाहते हैं। आप इस तरह की उपलब्धि कैसे पूरा करेंगे?
जोड़ा लेखक Marchy, स्रोत
@romkyns एक वर्ग के लिए, हाँ। एक संरचना के लिए, नहीं। सी # आपको structs के लिए बेस कन्स्ट्रक्टर को कॉल करने की इजाजत नहीं देता है ताकि यह सुनिश्चित किया जा सके कि वे सचेत रहें (और) कक्षाओं के लिए बोर्डों में चीजों को समान रखें। (सी ++ की तुलना करें, जहां वही बात सच है, स्टैक पर ढेर या ढेर विकल्प को छोड़कर कॉल कोड में बजाए कोड कोड में किया जाता है, और एक ही सीमा जगह पर है)
जोड़ा लेखक Jasper, स्रोत
@JonLimjap इसका मतलब है कि आप एक कन्स्ट्रक्टर के साथ टेम्पलेट विधि पैटर्न को लागू नहीं कर सकते हैं?
जोड़ा लेखक Sebastien, स्रोत
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}
0
जोड़ा

यदि आपको बेस कन्स्ट्रक्टर को कॉल करने की आवश्यकता है लेकिन तुरंत नहीं, क्योंकि आपकी नई (व्युत्पन्न) कक्षा को कुछ डेटा मैनिपुलेशन करने की आवश्यकता है, तो सबसे अच्छा समाधान फैक्ट्री विधि का सहारा लेना है। आपको अपने व्युत्पन्न कन्स्ट्रक्टर को निजी रूप से चिह्नित करना है, फिर अपनी कक्षा में एक स्थिर विधि बनाएं जो सभी आवश्यक सामग्री करेगी और बाद में कन्स्ट्रक्टर को कॉल करेगी और ऑब्जेक्ट को वापस कर देगी।

public class MyClass : BaseClass
{
    private MyClass(string someString) : base(someString)
    {
        //your code goes in here
    }

    public static MyClass FactoryMethod(string someString)
    {
        //whatever you want to do with your string before passing it in
        return new MyClass(someString);
    }
}
0
जोड़ा
यह संभावित सोलिड सिद्धांतों (एसआरपी) का उल्लंघन कर सकता है, क्योंकि कक्षा बनाने की ज़िम्मेदारी वर्ग की देखभाल करने के लिए किसी अन्य जिम्मेदारी के साथ समाहित है। एक अमूर्त कारखाने का उपयोग किया जा सकता है लेकिन सरल कोड में अनावश्यक जटिलता जोड़ सकता है। निश्चित रूप से एसओएलआईडी का उल्लंघन ठीक है यदि आप व्यापार को जानते हैं और टोल यह आपके आर्किटेक्चर (और आपके डिज़ाइन निर्णय से उत्पन्न होने वाले किसी भी भविष्य के मुद्दों को कैसे ठीक कर सकता है) को डालने जा रहा है।
जोड़ा लेखक Sebastien, स्रोत

ध्यान दें कि आप बेस कन्स्ट्रक्टर को कॉल के भीतर स्थिर विधियों का उपयोग कर सकते हैं।

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo) : 
         base(ModifyMessage(message, extraInfo))
     {
     }

     private static string ModifyMessage(string message, string extraInfo)
     {
         Trace.WriteLine("message was " + message);
         return message.ToLowerInvariant() + Environment.NewLine + extraInfo;
     }
}
0
जोड़ा
क्षमा करें, सी # newb यहाँ। आप Trace.WriteLine ("संदेश था" + संदेश) क्यों कहते हैं?
जोड़ा लेखक kdbanman, स्रोत
इस बारे में बिल्कुल कुछ भी हानिकारक नहीं है जब तक कि मध्यवर्ती कार्य नैतिक रूप से स्टेटलेस है। लॉगिंग एक अच्छा उपयोग केस नहीं है, आईएमओ, लेकिन आवरण को सामान्यीकृत करना या अतिरिक्त जोड़ना ठीक लगता है।
जोड़ा लेखक Aluan Haddad, स्रोत
@kdbanman जो सिर्फ एक डीबग संदेश आउटपुट करता है। कोई प्रासंगिक कार्यात्मक उद्देश्य नहीं।
जोड़ा लेखक Nick Whaley, स्रोत
यह बहुत सोलिड नहीं दिखता है (यदि आप जानते हैं कि मेरा क्या मतलब है) (... एसआरपी ...)
जोड़ा लेखक Sebastien, स्रोत
अपवाद वर्ग इतनी तालाब है कि मुझे यह दो बार ऐसा करने लगता है, लेकिन यह भी ध्यान दें कि अगर आप इससे बच सकते हैं तो ऐसा कुछ नहीं करना चाहिए।
जोड़ा लेखक SMASH, स्रोत
हाय @ क्रिसिस, क्या मैं `: आधार (" मेरा डिफ़ॉल्ट संदेश ") का उपयोग कर सकता हूं, 'इस तरह का उपयोग कैसे करें?
जोड़ा लेखक Carlos, स्रोत
बहुत बढ़िया जवाब। स्वीकृत उत्तर मुझे प्रसंस्करण करने की अनुमति नहीं देता है; और वर्कअराउंड पर फॉलोअप टिप्पणी मानता है कि मेरे पास पहुंच है आधार वर्ग बदलें; मैं नही। एक फैक्ट्री उत्तर मानता है कि मैं नियंत्रित कर सकता हूं कि कक्षा को कैसे तत्काल किया जाता है; ई कैन'टी। केवल आपका जवाब मुझे इसे आधार पर पास करने से पहले कुछ संशोधित करने देता है।
जोड़ा लेखक The Red Pea, स्रोत
इसके लिए बहुत बहुत धन्यवाद, मुझे बेस कन्स्ट्रक्टर को पास करने के लिए मूल्य लाने के लिए का उपयोग करके डेटाबेस संदर्भ बनाने की आवश्यकता थी और मुझे नहीं पता था कि यह कैसे करें।
जोड़ा लेखक Micheal Johnson, स्रोत

आप एक सशर्त चेक भी कर सकते हैं और कन्स्ट्रक्टर में गुणों में गुजर सकते हैं, जो कुछ लचीलापन की अनुमति देता है।

public MyClass(object myObject=null): base(myObject ?? new myOtherObject())
{
}

या

public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
0
जोड़ा
आपको अपने उदाहरण से "कक्षा" शब्द को हटाने की आवश्यकता नहीं है क्योंकि ये निर्माता हैं ...
जोड़ा लेखक MarzSocks, स्रोत

From Framewयाk Design Guidelines and FxCop rules.:

1। कस्टम अपवाद का नाम होना चाहिए जो अपवाद के साथ समाप्त होता है

    class MyException : Exception

2। अपवाद सार्वजनिक होना चाहिए

    public class MyException : Exception

3। CA1032: अपवाद मानक कन्स्ट्रक्टर लागू करना चाहिए।

  • A public parameterless constructया.
  • A public constructया with one string argument.
  • A public constructया with one string and Exception (as it can wrap another Exception).
  • A serialization constructया protected if the type is not sealed and private if the type is sealed. Based on MSDN:

    [Serializable()]
    public class MyException : Exception
    {
      public MyException()
      {
        //Add any type-specific logic, and supply the default message.
      }
    
      public MyException(string message): base(message) 
      {
        //Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
        //Add any type-specific logic fया inner exceptions.
      }
      protected MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
        //Implement type-specific serialization constructया logic.
      }
    }  
    

या

    [Serializable()]
    public sealed class MyException : Exception
    {
      public MyException()
      {
        //Add any type-specific logic, and supply the default message.
      }

      public MyException(string message): base(message) 
      {
        //Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
        //Add any type-specific logic fया inner exceptions.
      }
      private MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
        //Implement type-specific serialization constructया logic.
      }
    }  
0
जोड़ा
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

आप रचनाकारों में से एक के लिए आंतरिक अपवाद पारित कर सकते हैं।

0
जोड़ा

बेस क्लास कन्स्ट्रक्टर को कॉल करने के लिए यह base (कुछ) का सही उपयोग है, लेकिन ओवरलोडिंग के मामले में यह कीवर्ड का उपयोग करें

public ClassName() : this(par1,par2)
{
// do not call the constructor it is called in the this.
// the base key- word is used to call a inherited constructor   
} 

// Hint used overload as often as needed do not write the same code 2 or more times
0
जोड़ा
मैं देखता हूं कि आप क्या समझाने की कोशिश कर रहे हैं, और आप सही हैं। यदि आपके पास एक वर्ग में दो रचनाकार हैं, तो आप विरासत कन्स्ट्रक्टर को कॉल करते समय "बेस" का उपयोग करने के तरीके के समान "इस" कीवर्ड का उपयोग करके दूसरे से संदर्भित कर सकते हैं। हालांकि, यह वही नहीं है जिसे ओपी ने पूछा था, इसलिए यह वास्तव में इसे जोड़ने का स्थान नहीं है।
जोड़ा लेखक IAmTimCorey, स्रोत
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}
0
जोड़ा

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

public class MyException : Exception
{
    public MyException(string message, string extraInfo) : base(message)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
       //You can omit the 'this.' portion above...
    }
}

मुझे लगता है कि आपके उदाहरण में आपने extraInfo पैरामीटर का कभी भी उपयोग नहीं किया है, इसलिए मुझे लगता है कि आप extraInfo स्ट्रिंग पैरामीटर को संदेश </कोड में जोड़ना चाहेंगे > आपके अपवाद की संपत्ति (ऐसा लगता है कि इसे स्वीकार किए गए उत्तर और आपके प्रश्न में कोड में अनदेखा किया जा रहा है)।

यह केवल बेस क्लास कन्स्ट्रक्टर का आह्वान करके और फिर अतिरिक्त जानकारी के साथ संदेश संपत्ति को अपडेट करके हासिल किया जाता है।

वैकल्पिक रूप से, जैसा कि संदेश संपत्ति को बेस क्लास से विरासत में मिला है, आपको बेस क्लास कन्स्ट्रक्टर को स्पष्ट रूप से कॉल करने की भी आवश्यकता नहीं है। आप सीधे अपनी विरासत कक्षा के निर्माता से संदेश संपत्ति को अपडेट कर सकते हैं, जैसे:

public class MyException : Exception
{
    public MyException(string message, string extraInfo)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
       //You can omit the 'this.' portion above...
    }
}
0
जोड़ा