C # में जावा-स्टाइल थ्रो कीवर्ड का उपयोग कैसे करें?


91

जावा में, throwsकीवर्ड यह घोषित करने के लिए एक विधि की अनुमति देता है कि वह स्वयं एक अपवाद को संभाल नहीं पाएगा, बल्कि इसे कॉलिंग विधि में फेंक देगा।

क्या C # में समान कीवर्ड / विशेषता है?

यदि कोई समकक्ष नहीं है, तो आप एक ही (या एक समान) प्रभाव को कैसे पूरा कर सकते हैं?

जवाबों:


78

जावा में, आपको या तो एक अपवाद को संभालना चाहिए या उस विधि को चिह्नित करना चाहिए जो throwsकीवर्ड का उपयोग करके इसे फेंक सकती है ।

C # में यह कीवर्ड या समतुल्य एक नहीं है, जैसा कि C # में है, यदि आप एक अपवाद को हैंडल नहीं करते हैं, तो यह बबल जाएगा, जब तक पकड़ा नहीं जाता है या यदि पकड़ा नहीं जाता है तो यह प्रोग्राम को समाप्त कर देगा।

यदि आप इसे संभालना चाहते हैं तो फिर से फेंक सकते हैं, आप निम्न कार्य कर सकते हैं:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}

1
"यह बुदबुदाएगा", क्या इसका मतलब यह है कि यह जावा में थ्रो क्लॉज वाले सभी तरीकों के बराबर है?
लुई Rhys

1
@ लुईस आरएच - तरह का। इसका मतलब एक अपवाद है, यदि संभाला नहीं गया है, तो प्रत्येक कॉलिंग फ़ंक्शन के माध्यम से हैंडल किए जाने तक कॉल श्रृंखला ऊपर जाएगी।
ओड

1
@ पूरी तरह से आरएच पूरी तरह से नहीं है, इसका मतलब है कि आपको कोड को संकलित करने के लिए कम से कम आप में अपवाद को पकड़ना होगा। क्योंकि C # चेक किए गए अपवादों को नहीं जानता है, इसलिए उन्हें पकड़ना आपके ऊपर है अन्यथा वे केवल रनटाइम में लैंड करेंगे और आपके कोड को बाधित करेंगे।
जोहान्स वाचर

1
@ जेवर: एक मुख्य विधि में थ्रो क्लॉज भी हो सकता है।
लुई राइस

4
@ आशीषकम्बल - एह। अभिप्राय का सबब। .NET में अपवाद हैंडलिंग अलग है। आप यह मत समझिए कि "बेहतर" क्या है।
ओड

107

ऑप्‍शन जावा के throwsक्‍लॉज के C # समतुल्य के बारे में पूछ रहा है - throwकीवर्ड नहीं । यह जावा में विधि हस्ताक्षरों में उपयोग किया जाता है ताकि यह इंगित किया जा सके कि एक अपवाद को फेंक दिया जा सकता है।

C # में, जावा जाँच अपवाद का कोई सीधा समकक्ष नहीं है। C # में कोई समान विधि हस्ताक्षर खंड नहीं है।

// Java - need to have throws clause if IOException not handled
public void readFile() throws java.io.IOException {
  ...not explicitly handling java.io.IOException...
}

में अनुवाद करता है

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}

30

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

यदि आप विजुअल स्टूडियो 2012 का उपयोग कर रहे हैं तो एक बिल्ट इन टूल है जिसका उपयोग आईडीई स्तर "थ्रो" के समकक्ष करने के लिए किया जा सकता है।

यदि आप ऊपर बताए अनुसार XML डॉक्यूमेंटेशन कमेंट्स का उपयोग करते हैं , तो आप विधि या वर्ग द्वारा फेंके गए अपवाद के प्रकार के साथ-साथ यह कब या क्यों फेंका गया है, यह बताने के लिए <अपवाद> टैग का उपयोग कर सकते हैं ।

उदाहरण:

    /// <summary>This method throws an exception.</summary>
    /// <param name="myPath">A path to a directory that will be zipped.</param>
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
    public void FooThrowsAnException (string myPath)
    {
        // This will throw an IO exception
        ZipFile.CreateFromDirectory(myPath);
    }

4
ओपी, यह आपका जवाब है। मैं अनुमान लगा रहा हूं, लेकिन throwsडेवलपर के लिए जानकारीपूर्ण होने से अलग, जेएवीए की संभावना का कोई मतलब नहीं है। इसी तरह, @mvanella ने यहां जो बताया, वह ठीक उसी तरह करने का C # तरीका है। मुझे लगता है कि आप पहले से ही जानते हैं कि इस "xml प्रलेखन" का अधिक महत्वपूर्ण उद्देश्य है। मुझे पता है कि यह धागा पुराना है।
हरि लुबोवैक

वास्तव में, जावा तब तक अपवादों का बुलबुला नहीं फोड़ता, जब तक कि वह स्पष्ट रूप से एक throwsखंड में निर्दिष्ट या throwकमांड द्वारा फेंका न जाए । इसका मतलब है कि अगर एक RunTimeException होती है और इसे उसी विधि से नियंत्रित नहीं किया जाता है जहां यह होता है, तो निष्पादन वहीं रुक जाएगा।
पेड्रो लीमा

18

यहाँ एक ऐसे ही प्रश्न का उत्तर दिया गया है जो मुझे अभी-अभी बाइट्स.कॉम पर मिला है :

संक्षिप्त जवाब नहीं है। C # में कोई अपवाद नहीं हैं। भाषा के डिजाइनर इस साक्षात्कार में इस निर्णय पर चर्चा करते हैं:

http://www.artima.com/intv/handcuffs.html

निकटतम आप अपने XML दस्तावेज़ों में टैग का उपयोग कर सकते हैं, और अपने कोड / असेंबली के साथ NDoc जनरेट किए गए डॉक्स वितरित कर सकते हैं ताकि अन्य लोग यह देख सकें कि आपके द्वारा फेंके गए अपवाद (MS MS प्रलेखन में वास्तव में MS क्या करते हैं)। आप संकलक पर भरोसा नहीं कर सकते हैं कि आप बिना किसी अपवाद के बता सकते हैं, हालांकि, जैसे कि आपको जावा में इस्तेमाल किया जा सकता है।


7

यहाँ अधिकांश उत्तरों से गुजरने के बाद, मैं कुछ विचार जोड़ना चाहूँगा।

  1. XML दस्तावेज़ीकरण टिप्पणियों पर भरोसा करना और दूसरों पर भरोसा करने की उम्मीद करना एक खराब विकल्प है। अधिकांश C # कोड जो मैं आया हूं, XML डॉक्यूमेंटेशन टिप्पणियों के साथ पूरी तरह से और लगातार दस्तावेज़ों का दस्तावेजीकरण नहीं करता है। और फिर वहाँ बड़ा मुद्दा है कि बिना C # में जाँच किए अपवाद है, आप अपने API उपयोगकर्ता के उद्देश्य से उन सभी अपवादों को कैसे दस्तावेज़ित कर सकते हैं, यह जानने के लिए कि उन सभी को व्यक्तिगत रूप से कैसे प्रबंधित किया जाए? याद रखें, आप केवल उन लोगों के बारे में जानते हैं जिन्हें आप अपने कार्यान्वयन में फेंक कीवर्ड के साथ फेंकते हैं। आपके द्वारा अपने पद्धति कार्यान्वयन के अंदर उपयोग किए जा रहे एपीआई भी अपवादों को फेंक सकते हैं, जिनके बारे में आप नहीं जानते हैं क्योंकि वे दस्तावेज नहीं हो सकते हैं और आप उन्हें अपने कार्यान्वयन में नहीं संभाल रहे हैं, इसलिए वे आपके फोन करने वाले के चेहरे को उड़ा देंगे। तरीका। दूसरे शब्दों में,

  2. एंड्रियास हेजेल्सबर्ग के साथ एक साक्षात्कार को यहां के जवाबों में सी # डिजाइन टीम द्वारा जाँच किए गए अपवादों के खिलाफ निर्णय लेने के कारण से जोड़ा गया। मूल प्रश्न का अंतिम उत्तर उस साक्षात्कार में छिपा है:

प्रोग्रामर अंत में हर जगह कोशिश करके अपने कोड की रक्षा करते हैं, इसलिए यदि कोई अपवाद होता है, तो वे सही ढंग से वापस करेंगे, लेकिन वे वास्तव में अपवादों को संभालने में रुचि नहीं रखते हैं।

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

-

व्यक्तिगत रूप से, मैं यहाँ फटा हूँ। मैं एंडर्स के साथ सहमत हूं कि नए अपवादों को अलग किए बिना समस्या की जाँच नहीं होती है। XML दस्तावेज़ टिप्पणियों के साथ की तरह, मैं शायद ही कभी C # कोड को अंत में ब्लॉक में लिपटे सब कुछ के साथ देखता हूं। यह मुझे लगता है, हालांकि यह वास्तव में आपका एकमात्र विकल्प है और कुछ ऐसा है जो एक अच्छा अभ्यास है।


3

वास्तव में C # में अपवादों की जाँच नहीं करना अच्छी या बुरी बात मानी जा सकती है।

मैं स्वयं इसे एक अच्छा उपाय मानता हूँ क्योंकि जाँच की गई अपवाद आपको निम्नलिखित समस्याएं प्रदान करते हैं:

  1. तकनीकी अपवाद व्यवसाय / डोमेन परत पर लीक हो रहे हैं क्योंकि आप उन्हें निम्न स्तर पर ठीक से संभाल नहीं सकते हैं।
  2. वे विधि हस्ताक्षर से संबंधित हैं जो हमेशा एपीआई डिजाइन के साथ अच्छा नहीं खेलता है।

क्योंकि सबसे बड़े अनुप्रयोगों में आप निम्न पैटर्न देखेंगे जब जाँच अपवाद होते हैं:

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

जो अनिवार्य रूप से सी # /। नेट का अनुकरण करने का अर्थ है सभी अपवादों को संभालता है।


मैं कल्पना नहीं कर सकता कि कैसे जाँच किए गए अपवाद लैम्ब्डा के साथ मिलेंगे!
गाबे

@ गैब: मुझे यकीन है कि आप कुछ अवधारणा के साथ आ सकते हैं जो आपको उन्हें मिश्रण करने की अनुमति देता है, लेकिन जैसा कि मैंने कहा, चेक किए गए अपवाद जावा में भी ज्यादातर अच्छे अभ्यास नहीं हैं, खासकर अधिक जटिल अनुप्रयोगों में। इसलिए यह अच्छा है कि वे सी # में नहीं हैं।
जोहान्स वाचर

3

आप इस बारे में पूछ रहे हैं:

एक अपवाद को फिर से फेंकना

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

या

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }

3
उपयोग करने के लिए +1 throw। इसका उपयोग करके, स्टैक ट्रेस खो नहीं जाएगा।
Giuseppe Accaputo

2

.नेट कोडकॉन्ट्रैक्ट EnsuresOnThrow<>और जावा throwsडिस्क्रिप्टर के बीच कुछ क्षणभंगुर समानताएं हैं , जिसमें दोनों कॉलर को अपवाद के प्रकार के रूप में संकेत दे सकते हैं जो किसी फ़ंक्शन या विधि से उठाया जा सकता है, हालांकि 2 के बीच भी बड़े अंतर हैं

  • EnsuresOnThrow<>केवल यह बताते हुए कि अपवाद को फेंका जा सकता है, लेकिन उन शर्तों को भी निर्धारित करता है जिनके तहत उन्हें फेंके जाने की गारंटी दी जाती है - यह कॉल विधि में काफी महत्वपूर्ण कोड हो सकता है यदि अपवाद स्थिति की पहचान करने के लिए तुच्छ नहीं है। जावा throwsएक संकेत प्रदान करता है कि किन अपवादों को फेंका जा सकता है (यानी आईएमओ में फोकस .Net उस विधि के अंदर है जो साबित करने के लिए अनुबंध करता है throw, जबकि जावा में फोकस अपवाद की संभावना को स्वीकार करने के लिए कॉल करने वाले को स्थानांतरित कर देता है)।
  • .नेट CC , जावा के पास चेक किए गए बनाम अनियंत्रित अपवादों के बीच भेद नहीं करता है, हालाँकि CC मैन्युअल सेक्शन 2.2.2 का उल्लेख नहीं है

"असाधारण अपवादों का उपयोग केवल उन अपवादों के लिए करें जो एक कॉलर को एपीआई के हिस्से के रूप में उम्मीद करनी चाहिए"

  • .Net में कॉलर यह निर्धारित कर सकता है कि अपवाद के साथ कुछ भी किया जाए या नहीं (जैसे अनुबंधों को अक्षम करके)। जावा में, कॉलर को कुछ करना चाहिए , भले ही वह throwsअपने इंटरफ़ेस पर समान अपवाद के लिए जोड़ता हो ।

कोड अनुबंध मैनुअल यहाँ


0

यदि c # विधि का उद्देश्य केवल एक अपवाद को फेंकना है (जैसे js रिटर्न प्रकार कहता है) तो मैं उस अपवाद को वापस करने की सलाह दूंगा। उदाहरण देखें bellow:

    public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
    {
        return new EntityNotFoundException($"The object '{entityType.Name}' with given id '{id}' not found.");
    }

    public TEntity GetEntity<TEntity>(string id)
    {
        var entity = session.Get<TEntity>(id);
        if (entity == null)
            throw GetEntityNotFoundException(typeof(TEntity), id);
        return entity;
    }


-1

आश्चर्य करने वालों के लिए, आपको यह परिभाषित करने की आवश्यकता नहीं है कि आप इसे अगली विधि में पास करने के लिए क्या पकड़ते हैं। यदि आप चाहते हैं कि आपकी सभी त्रुटि एक मुख्य थ्रेड में हो तो आप बस सब कुछ पकड़ सकते हैं और इसे इस तरह से पास कर सकते हैं:

try {
    //your code here
}
catch {
    //this will throw any exceptions caught by this try/catch
    throw;
}

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