declare a method always throws an exception?

2019-04-18 02:33发布

I have a method like...

int f() {
  try {
    int i = process();
    return i;
  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
}

This produces a compiler error, "not all code paths return a value". But in my case ThrowSpecificFault() will always throw (the appropriate) exception. So I am forced to a put a return value at the end but this is ugly.

The purpose of this pattern in the first place is because "process()" is a call to an external web service but need to translate a variety of different exceptions to match a client's expected interface (~facade pattern I suppose).

Any cleaner way to do this?

11条回答
兄弟一词,经得起流年.
2楼-- · 2019-04-18 02:45

How about:

int f() {
 int i = -1;
 try {
   i = process();       
 } catch(Exception ex) {
   ThrowSpecificFault(ex);
 }
 return i;
}
查看更多
我想做一个坏孩纸
3楼-- · 2019-04-18 02:48

Right now a return type can be a type, or "void" meaning "no return type". We could in theory add a second special return type "never", which has the semantics you want. The end point of an expression statement consisting of a call to a "never" returning method would be considered unreachable, and so it would be legal in every context in C# in which a "goto", "throw" or "return" is legal.

It is highly unlikely that this will be added to the type system now, ten years in. Next time you design a type system from scratch, remember to include a "never" type.

查看更多
Viruses.
4楼-- · 2019-04-18 02:54

I suppose you could make ThrowSpecificFault return an Object, and then you could

return ThrowSpecificFault(ex)

Otherwise, you could rewrite ThrowSpecificFault as a constructor for an Exception subtype, or you could just make ThrowSpecificFault into a factory that creates the exception but doesn't throw it.

查看更多
狗以群分
5楼-- · 2019-04-18 02:56

No.

Imagine if ThrowSpecificFault were defined in a separate DLL. If you modify the DLL to not throw an exception, then run your program without recompiling it, what would happen?

查看更多
成全新的幸福
6楼-- · 2019-04-18 02:57

The problem here, is that if you go into the catch block in f() your function will never return a value. This will result in an error because you declared your function as int which means you told the compiler that your method will return an integer.

The following code will do what you are looking for and always return an integer.

int f() {
  int i = 0;
  try {
    i = process();

  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
  return i;
}

put the return statement at the end of your function and you will be fine.

It's always a good idea to ensure your method will always return a value no matter what execution path your application goes through.

查看更多
狗以群分
7楼-- · 2019-04-18 02:59

In you case but that is Your knowledge not the compiler. There is now way to say that this method for sure will throw some nasty exception.

Try this

int f() {
  try {
    return process();
  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
  return -1;
}

You can also use the throw key word

int f() {
  try {
    return process();
  } catch(Exception ex) {
    throw ThrowSpecificFault(ex);
  }
}

But then that method should return some exception instead of throwing it.

查看更多
登录 后发表回答