使用自定义异常C#返回信息

时间:2016-10-01 16:15:39

标签: c# exception custom-exceptions

我有以下问题:

  1. 我有一个服务方法:

    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
    }
    
  2. GetEmployeeWorkingHours只是检查员工是否可以领取薪水的方法之一(因此雇主可能有其他原因不付款)。出于这些原因,我想提出一个例外,其中包含适当的信息:所需工作时数,实际工作时数等。

    问题是:

    是否有办法使用我的自定义异常返回对象或其他信息。另外,我指的是一个物体或几个参数。

2 个答案:

答案 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 { ... });