2009-07-08 4 views
5

जब कस्टम अपवाद के साथ काम कर, मैं आमतौर पर अपवाद से विरासत और फिर कुछ फ़ील्ड्स जोड़ने/मेरी अपवाद वर्ग के लिए गुण कुछ अतिरिक्त जानकारी स्टोर करने के लिए:कस्टम अपवादों के अंदर डेटा को कैसे स्टोर किया जाना चाहिए?

public class MyException : Exception 
{ 
    public int ErrorCode{get;set;} 

    public MyException() 
    {} 
} 

उपरोक्त उदाहरण में, ErrorCode मूल्य अपवाद में संग्रहित है , जिसका मतलब है कि मुझे इसे संरक्षित कन्स्ट्रक्टर में SerializationInfo ऑब्जेक्ट से और GetObjectData विधि से अधिक ऑब्जेक्ट से जोड़ना होगा और फिर से सेवानिवृत्त करना होगा।

कुंजी/मान जोड़े कि अपवाद के बारे में अतिरिक्त उपयोगकर्ता परिभाषित जानकारी प्रदान करते हैं का संग्रह हो जाता है:

Exception वर्ग एक Data संपत्ति है, जो MSDN के अनुसार है।

अगर मैं Data अंदर त्रुटि कोड की दुकान, यह (परावर्तक के अनुसार) अपवाद वर्ग से मेरे लिए धारावाहिक मिल जाएगा, जिसका अर्थ है कि मेरी अपवाद वर्ग अब की तरह दिखता है:

public class MyException : Exception 
{ 
    public int ErrorCode 
    { 
     get {return (int) Data["ErrorCode"];} 
     set {Data["ErrorCode"] = value;} 
    } 

    public MyException() 
    {} 
} 

यह साधन कि त्रुटि कोड के प्राप्त/सेट से निपटने में थोड़ा और काम है (जैसे कास्टिंग त्रुटियों और परिस्थितियों से निपटने की तरह जहां त्रुटि कोड शब्दकोश में नहीं हो सकता है), मुझे serialising के बारे में चिंता करने की ज़रूरत नहीं है/deserialising।

क्या यह एक ही चीज़ को प्राप्त करने के केवल दो अलग-अलग तरीकों से है, या किसी अन्य तरीके से दूसरे पर कोई स्पष्ट लाभ नहीं है (उन लोगों के अलावा जिन्हें मैंने पहले ही उल्लेख किया है)?

उत्तर

1

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

public static void TestCustomException<T>() where T : Exception 
{ 
    var t = typeof(T); 

    //Custom exceptions should have the following 3 constructors 
    var e1 = (T)Activator.CreateInstance(t, null); 

    const string message = "message"; 
    var e2 = (T)Activator.CreateInstance(t, message); 
    Assert.AreEqual(message, e2.Message); 

    var innerEx = new Exception("inner Exception"); 
    var e3 = (T)Activator.CreateInstance(t, message, innerEx); 
    Assert.AreEqual(message, e3.Message); 
    Assert.AreEqual(innerEx, e3.InnerException); 

    //They should also be serializable 
    var stream = new MemoryStream(); 
    var formatter = new BinaryFormatter(); 
    formatter.Serialize(stream, e3); 
    stream.Flush(); 
    stream.Position = 0; 
    var e4 = (T)formatter.Deserialize(stream); 
    Assert.AreEqual(message, e4.Message); 
    Assert.AreEqual(innerEx.ToString(), e4.InnerException.ToString()); 
} 
0

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

यदि आपके पास अपना स्वयं का अपवाद प्रकार है, तो इसके बजाय गुणों का उपयोग करें: यह अधिक स्वच्छ और सुरक्षित है।

1

Microsoft's own guidelines:

अपवाद serializable बनाने है। एक अपवाद आवेदन डोमेन भर में सही ढंग से काम करने और सीमाओं को रिमोट करने के लिए serializable होना चाहिए।

मैं इसे डेटा-प्रॉपर्टी में संग्रहीत करता हूं जो दुख से बाहर कोड को सहमति के बिना मूल्य को संशोधित करने देता है, या समाधान 1 (आपके उदाहरण में) का उपयोग करता है लेकिन इसे क्रमबद्ध बनाता है। अंत में मैं शायद समाधान 1 के लिए जाऊंगा, इसलिए मैं यह सुनिश्चित कर सकता हूं कि मूल्य कभी नहीं बदलेगा।

5

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

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