Basit cevap, bir işlem imkansız olduğunda (her iki uygulamadan dolayı VEYA iş mantığını ihlal edeceği için). Bir yöntem çağrılırsa ve yöntemin yazmak için yapması mümkün değilse, bir İstisna atın. Bunun iyi bir örneği, sağlanan parametreler kullanılarak bir örnek oluşturulamazsa kurucuların her zaman ArgumentExceptions parametrelerini atmasıdır. Başka bir örnek, sınıfın başka bir üyesinin veya üyelerinin durumu nedeniyle bir işlem gerçekleştirilemediğinde atılan InvalidOperationException örneğidir.
Sizin durumunuzda, Oturum Açma (kullanıcı adı, şifre) gibi bir yöntem çağrılırsa, kullanıcı adı geçerli değilse, gerçekten bir UserNameNotValidException veya şifre yanlışsa PasswordNotCorrectException özelliğinin kullanılması doğrudur. Kullanıcı, sağlanan parametreleri kullanarak oturum açamaz (yani, kimlik doğrulamasını ihlal edeceği için imkansızdır), bu nedenle bir İstisna atın. Her ne kadar iki istisna ArgumentException devralmak olabilir.
Bir oturum açma hatası çok yaygın olabileceğinden bir İstisna atmak istemiyorsanız, bir strateji bunun yerine farklı hataları temsil eden türleri döndüren bir yöntem oluşturmaktır. İşte bir örnek:
{ // 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))
{ }
}
Çoğu geliştiriciye, onları fırlatmanın neden olduğu ek yük nedeniyle İstisnalardan kaçınmaları öğretilir. Kaynağa duyarlı olmak harikadır, ancak genellikle uygulama tasarımınızın pahasına değildir. Muhtemelen iki İstisnalarınızı atmamanızın size söylenmesinin nedeni budur. İstisnaların kullanılıp kullanılmayacağı genellikle Kural Dışı Durumun ne sıklıkta gerçekleşeceğine bağlıdır. Oldukça yaygın veya oldukça beklenen bir sonuç ise, çoğu geliştiricinin İstisnalardan kaçınacağı ve bunun yerine kaynakların sözde tüketimi nedeniyle başarısızlığı göstermek için başka bir yöntem oluşturacağı zamandır.
Try () desenini kullanarak, az önce anlatıldığı gibi bir senaryoda Özel Durumlar kullanmaktan kaçınmanın bir örneği:
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;
}
}