I personally don't like to program arround return values / Enum
types. The more return types you have, the more paths you have to test / work with. Also, using exceptions to control flow is imo a bad practice (Unless you really can't find any other option - but there's usually a better one).
An expired password is not really exceptional to me. Its a valid state after all (Or else you'd do something against passwords to expire at all)
I try to keep it simple and either return a bool
or something like a Func<T>
which can be directly invoked by the caller.
Probably something like that:
public class User
{
private DateTime _lastChangeDate;
public Action Validate()
{
if (_lastChangeDate >= DateTime.Now.AddDays(-30))
{
return new Action(() => this.Login());
}
else
{
return new Action(() => this.ChangePassword());
}
}
private void Login()
{
Console.WriteLine("Login");
}
private void ChangePassword()
{
Console.WriteLine("Change Password");
}
}
On the caller side:
user.Validate().Invoke();