use*_*472 30 c# attributes exception return-type
我有一个看起来像这样的方法:
void throwException(string msg)
{
throw new MyException(msg);
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我写
int foo(int x, y)
{
if (y == 0)
throwException("Doh!");
else
return x/y;
}
Run Code Online (Sandbox Code Playgroud)
编译器会抱怨foo"并非所有路径都返回一个值".
是否有一个属性我可以添加到throwException以避免这种情况?就像是:
[NeverReturns]
void throwException(string msg)
{
throw new MyException(msg);
}
Run Code Online (Sandbox Code Playgroud)
我担心自定义属性不会这样做,因为为了我的目的,我需要编译器的合作.
ber*_*hof 32
为什么不改变它
int foo(int x, y)
{
if (y == 0)
throwException("Doh!");
return x/y;
}
Run Code Online (Sandbox Code Playgroud)
这给出了相同的运行时结果,编译器不会抱怨.
Dav*_*d M 22
不.我建议您更改第一个函数的签名以返回异常而不是抛出异常,并将throw语句保留在第二个函数中.这将使编译器保持高兴,并且闻起来也不那么糟糕.
Chr*_*ter 10
伯恩霍夫的回答是正确的.但是,如果您在实例化异常时尝试封装大量逻辑,那么您需要做的就是更改代码:
void throwException(string msg) {
throw new MyException(msg);
}
Run Code Online (Sandbox Code Playgroud)
对此:
Exception makeException(string msg) {
return new MyException(msg);
}
Run Code Online (Sandbox Code Playgroud)
那么你的调用代码将如下所示:
int foo(int x, y) {
if (y == 0) {
throw makeException("Doh!");
}
return x / y;
}
Run Code Online (Sandbox Code Playgroud)
在所有其他条件相同的情况下,更喜欢功能代码到程序代码.它更容易重复使用和单元测试.
编辑:
根据Fred的示例代码,这就是我要做的.这不是代码合同,但它仍然有效.
private int getVarID(string s_varID) {
int varID;
if(s_varID == "ILT") {
return 123;
} else if(s_varID == "TL") {
return 456;
} else if(s_varID == "FT") {
return 789;
} else if(int.TryParse(s_varID, out varID)) {
return varID;
} else {
throw makeParseError("varID must be an integer or 'ILT', 'TL' or 'FT'.");
}
}
Run Code Online (Sandbox Code Playgroud)
[DoesNotReturn]in的属性System.Diagnostics.CodeAnalysis应该是你想要的。
参考:https : //docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.doesnotreturnattribute?view=netcore-3.1
您可以通过使用泛型来声明函数返回"任何内容"来指示"永不返回":
T ThrowException<T>(string msg)
{
throw new MyException(msg);
}
Run Code Online (Sandbox Code Playgroud)
所以现在你可以写:
int foo(int x, int y)
{
if (y == 0)
return ThrowException<int>("Doh!");
else
return x/y;
}
Run Code Online (Sandbox Code Playgroud)
这个成语用于像Haskell和F#这样的语言,并且基于爆炸原理,也被称为"ex falso quodlibet".原因是:如果一个函数永远不会返回,那么我们可以对它的返回值做出我们想要的任何神奇假设,因为这样的值永远不会存在.这里,调用者(foo)假设ThrowException将返回一个int.
一些小缺点:
ThrowException可以通过返回来绕过这个default(T).ThrowException(Haskell和F#可以推断它).正如其他答案所说的那样,你可能最好还是退回异常而不是扔掉它.
| 归档时间: |
|
| 查看次数: |
3528 次 |
| 最近记录: |