我有以下问题:
我有一个服务方法:
public bool EmployeeCanReiceivePayment(int employeeId)
{
...
int workingHours = this.GetEmployeeWorkingHours(employeeId);
if(workingHours < N)
{
throw new EmployeeCannotReceivePaymentException();
}
return true;
}
public int GetEmployeeWorkingHours(int employeeId)
{
//returns the number of working hours of the employee for the last month
}
GetEmployeeWorkingHours只是检查员工是否可以领取薪水的方法之一(因此雇主可能有其他原因不付款)。出于这些原因,我想提出一个例外,其中包含适当的信息:所需工作时数,实际工作时数等。
问题是:
是否有办法使用我的自定义异常返回对象或其他信息。另外,我指的是一个物体或几个参数。
答案 0 :(得分:4)
避免使用控制流的例外
这是.NET Framework使用规则
DA0007: Avoid using exceptions for control flow
使用异常处理程序作为常规程序执行的一部分 逻辑可能很昂贵,应该避免。在多数情况下, 例外应仅用于发生的情况 很少见,不是预期的。
不是抛出异常而是创建一个包含所有必需信息的类。
public class PaymentValidation
{
public bool IsValid { get; set;}
public YourType SomeAdditionalInformation { get; set;}
}
public PaymentValidation EmployeeCanReiceivePayment(int employeeId)
{
int workingHours = this.GetEmployeeWorkingHours(employeeId);
var validationResult = new PaymentValidation();
validationResult.IsValid = true;
if(workingHours < N)
{
validationResult.IsValid = false;
}
return validationResult;
}
返回自己的类型将为进一步更改提供更多可能性。
例如,创建一个表示返回类型的接口。并为您拥有的每个案例创建自己的实施
public interface IPayment
{
void Pay();
}
为每个案例实施接口
public class NotEnoughWorkingHoursPayment : IPayment
{
public void Pay()
{
//Do nothing or log failed payment or inform user about it
}
}
public class SuccesfullPayment : IPayment
{
public void Pay()
{
//Execute payment
}
}
public class PaymentService
{
public IPayment ValidatePayment()
{
const int MIN_WORKING_HOURS = 40;
int workingHours = this.GetEmployeeWorkingHours(employeeId);
if(workingHourse < MIN_WORKING_HOURS)
{
return New NotEnoughWorkingHoursPayment();
}
return new SuccesfullPayment();
}
}
然后使用将是非常容易和可理解的
IPayment payment = paymentService.ValidatePayment();
payment.Pay();
答案 1 :(得分:1)
我同意其他人在这里所说的那样,通过例外强制执行BL不是一个好习惯。您可以返回包含成功状态+详细信息和有效返回数据的“ResultObject”,而不是异常。
但是如果你选择这样做,那么自定义你的自定义异常以包含不仅仅是一个默认的构造函数。他们就像任何其他类一样。类似的东西:
public class MyCustomException : Exception
{
//This is like you have now
public MyCustomException() { }
//This is if you want to have different messages
public MyCustomException(string message) : base(message{ }
//This is if you want to have different data to add (don't use object but a custom type
public MyCustomException(object yourObject)
{
YourObject = yourObject;
}
public object YourObject { get; set; }
}
在您的场景中,可能会出现类似的情况:
public class EmployeeException : Exception { ... }
//Add what you need from the example above
//Then when needed:
new EmployeeException("some text for this error");
new EmployeeException("some other text for this error");
//Or when with a proper object to describe more details:
new EmployeeException(new NotEnoughHours { ... });