简体   繁体   中英

Checking argument to avoid try..catch block ( ? )

I wrote this method in the .svc file

 public SomeDTO Method1( byte[] bitmapAsByteArr, DTO1 dto1, DTO2 dto2 )
    {
        if( bitmapAsByteArr!= null && bitmapAsByteArr.Length > 0 && dto1!= null && dto2 != null )
        {
            return new SomeDTO(bitmapAsByteArr,dto1,dto2,1,2,3,4);
        }
        else
        {
            throw new ArgumentNullException();
        }
    }

I was wander if this way is better them make the body of this method in try..catch block. What is better in this case ?

It depends on how likely it is that the arguments will be invalid. Are invalid arguments exceptional or expected .

A try...catch block will result in cleaner code and faster execution for the normal case, but the error case will execute more slowly.

So if this method gets called many times with invalid data this will be a potential slow point in your application and having code in the form you have will be slightly more efficient.

The pattern you are using here is wrong in that it returns an exception instead of throwing it. I think that is a error in the question, otherwise your SomeDTO object would have to be somehow connected with the ArgumentNullException class, and that's plain wrong.

What you can do is:
- Your solution, where we check all the arguments for validity, and then do the work

if (are_all_arguments_ok)
{
   //procedure code, possibly hundreds of lines
}
else
{
   throw new SingleExceptionForAnyParameterIssues();
}

- Embed the code in a try..catch , like

try
{
   //procedure code, possibly hundreds of lines
}
catch
{
   //not really sure what we caught here
   //could be a parameter problem, could be a code problem
   throw new SingleExceptionForAnyParameterIssues();
}

- check the parameters at the head of the method

if (param1_is_null)
{
   throw new ArgumentNullException("param1");
}
if (param1_is_invalid)
{
   throw new ArgumentException("bad, bad param1","param1");
}
// other parameters are checked here

//procedure code, possibly hundreds of lines

I (obviuosly) prefere the third method because:

  • It gives a clear separation of code that checks for parameter validity, and code that does the actual work
  • It enables more fine grained checks instead of a single check that basically tells me that something is wrong without specifying what
  • It's at the beginning of a method, and can be hidden in a region, so I don't need to focus on it when I review the corectness of the method proper code.
  • It's easy to add or change the throws to Asserts, logging statement or whatever is actually needed

如果您使用的是.NET 4.0,则可以使用Code Cotracts

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM