सरल उत्तर है, जब भी कोई ऑपरेशन असंभव होता है (या तो आवेदन के कारण या क्योंकि यह व्यापारिक तर्क का उल्लंघन होगा)। यदि कोई विधि लागू की जाती है और यह करना असंभव है कि विधि क्या करने के लिए लिखी गई है, तो अपवाद को फेंक दें। एक अच्छा उदाहरण यह है कि निर्माणकर्ता हमेशा ArgumentException को फेंक देते हैं यदि आपूर्ति मापदंडों का उपयोग करके एक उदाहरण नहीं बनाया जा सकता है। एक अन्य उदाहरण InvalidOperationException है, जिसे तब फेंक दिया जाता है जब किसी अन्य सदस्य या वर्ग के सदस्यों की स्थिति के कारण कोई ऑपरेशन नहीं किया जा सकता है।
आपके मामले में, यदि लॉगिन (उपयोगकर्ता नाम, पासवर्ड) जैसी कोई विधि लागू की जाती है, यदि उपयोगकर्ता नाम मान्य नहीं है, तो यह वास्तव में सही है कि पासवर्ड गलत है तो UserNameNotValidException, या PasswordNotCorrectException को फेंकना सही है। उपयोगकर्ता को दिए गए पैरामीटर (ओं) का उपयोग करके लॉग इन नहीं किया जा सकता है (अर्थात यह असंभव है क्योंकि यह प्रमाणीकरण का उल्लंघन करेगा), इसलिए एक अपवाद फेंकें। हालाँकि, मुझे आपके दो अपवाद ArgumentException से विरासत में मिल सकते हैं।
यह कहते हुए कि, यदि आप एक अपवाद को फेंकना नहीं चाहते हैं क्योंकि एक लॉगिन विफलता बहुत सामान्य हो सकती है, तो एक रणनीति इसके बजाय एक ऐसी विधि का निर्माण करना है जो विभिन्न प्रकारों का प्रतिनिधित्व करती है जो विभिन्न विफलताओं का प्रतिनिधित्व करते हैं। यहाँ एक उदाहरण है:
{ // class
...
public LoginResult Login(string user, string password)
{
if (IsInvalidUser(user))
{
return new UserInvalidLoginResult(user);
}
else if (IsInvalidPassword(user, password))
{
return new PasswordInvalidLoginResult(user, password);
}
else
{
return new SuccessfulLoginResult();
}
}
...
}
public abstract class LoginResult
{
public readonly string Message;
protected LoginResult(string message)
{
this.Message = message;
}
}
public class SuccessfulLoginResult : LoginResult
{
public SucccessfulLogin(string user)
: base(string.Format("Login for user '{0}' was successful.", user))
{ }
}
public class UserInvalidLoginResult : LoginResult
{
public UserInvalidLoginResult(string user)
: base(string.Format("The username '{0}' is invalid.", user))
{ }
}
public class PasswordInvalidLoginResult : LoginResult
{
public PasswordInvalidLoginResult(string password, string user)
: base(string.Format("The password '{0}' for username '{0}' is invalid.", password, user))
{ }
}
ज्यादातर डिवेलपर्स को एक्सेप्शन से बचने के लिए सिखाया जाता है क्योंकि ओवरहेड फेंकने के कारण होता है। संसाधन-सचेत होना बहुत अच्छा है, लेकिन आमतौर पर आपके एप्लिकेशन डिज़ाइन की कीमत पर नहीं। शायद यही कारण है कि आपको अपने दो अपवादों को नहीं फेंकने के लिए कहा गया था। अपवाद का उपयोग करना है या नहीं, आमतौर पर यह उबलता है कि अपवाद कितनी बार होगा। यदि यह एक बहुत ही सामान्य या काफी अपेक्षित परिणाम है, तो यह तब है जब अधिकांश डेवलपर्स अपवादों से बचेंगे और इसके बजाय संसाधनों की कथित खपत के कारण विफलता को इंगित करने के लिए एक और तरीका तैयार करेंगे।
यहाँ एक उदाहरण में अपवादों से बचने का उदाहरण दिया गया है, जैसे कि आजमाए गए () पैटर्न का उपयोग करके:
public class ValidatedLogin
{
public readonly string User;
public readonly string Password;
public ValidatedLogin(string user, string password)
{
if (IsInvalidUser(user))
{
throw new UserInvalidException(user);
}
else if (IsInvalidPassword(user, password))
{
throw new PasswordInvalidException(password);
}
this.User = user;
this.Password = password;
}
public static bool TryCreate(string user, string password, out ValidatedLogin validatedLogin)
{
if (IsInvalidUser(user) ||
IsInvalidPassword(user, password))
{
return false;
}
validatedLogin = new ValidatedLogin(user, password);
return true;
}
}