标签: throw

C#中的异常如何工作(幕后)

与" 如何在C++中实现异常(在幕后) "相同,但对于C#.

我知道抛出异常时必须执行以下步骤.

  1. 找到异常类型的最近处理程序;
  2. 将堆栈展开到处理程序级别;
  3. 调用处理程序;
  4. 查找并调用每个finally块.

.NET如何处理这些操作?"当前"处理程序的映射如何工作?try/catch块中发出了多少代码?在一个扔石块?

.net c# exception try-catch throw

19
推荐指数
2
解决办法
2525
查看次数

如何在Haskell中抛出异常并退出程序?

我有一个问题:如何抛出异常并退出程序?我写了一个简单的例子:

-- main.hs
import Test

main = do
    Test.foo ""
    putStrLn "make some other things"
Run Code Online (Sandbox Code Playgroud)

这是模块:

moldule Test where

foo :: String -> IO ()
foo x = do
    if null x
    then THROW EXCEPTION AND EXIT MAIN else putStrLn "okay"
Run Code Online (Sandbox Code Playgroud)

我想启动它并抛出异常并退出程序,但是如何?

haskell exception throw

17
推荐指数
1
解决办法
7475
查看次数

Java lambda只抛出表达式而不是语句式

在Java(目前使用Java 8)中,我可以编写这个并且所有编译都很好:

Supplier<Long> asd = () -> {
    throw new RuntimeException();
};
Run Code Online (Sandbox Code Playgroud)

但是,我不能这样写:

Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么Java的实现不允许这样的样式(表达式lambda)和只有语句/代码块样式lambda?

我的意思是,由于lambda 抛出RuntimeException,为什么JDK不能将lambda表达式推断为:

new Supplier<Long>() {
    @Override
    public Long get() {
        throw new RuntimeException();
    }
};
Run Code Online (Sandbox Code Playgroud)

这是在specs/docs中的某处记录的吗?这是仅在JDK> 8中添加的吗?

java lambda throw java-8 functional-interface

17
推荐指数
2
解决办法
553
查看次数

抛出接口中未定义的异常

当您需要抛出未在您正在实现的接口中定义的异常时,要遵循的最佳实践是什么?

这是一个例子:

public interface Reader
{
    public abstract void read() throws IOException;
}

public class CarrotReader implements Reader
{
    public void read() throws IOException {}
}

public class CupcakeReader implements Reader
{
    public void read() throws IOException, CupcakeException {}
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您在阅读纸杯蛋糕时会发生特定的异常,因此您希望抛出与此相关的异常.但是,Reader没有在其界面中定义此类异常,那么您如何做?此外,将CupcakeException添加到Reader接口中的throws子句没有意义,因为这种类型的异常特定于CupcakeReader.解决这个问题的一种方法是让Reader定义read,使其抛出一些父类型,如Exception,但是你会丢失异常的上下文.在这种情况下你应该怎么做?谢谢!


已经提出的另一个有趣的情况涉及一个你无法控制的界面.在这种情况下,表明问题发生的最佳方法是什么?

为了便于说明,这是另一个例子:

public interface Reader
{
    public abstract void read();
}

public class CupcakeReader implements Reader
{
    public void read() throws CupcakeException {} …
Run Code Online (Sandbox Code Playgroud)

java interface exception throw

16
推荐指数
2
解决办法
1万
查看次数

为什么在这种情况下允许抛出已检查的异常类型?

我偶然注意到这个throw语句(从一些更复杂的代码中提取)编译:

void foo() {
    try {

    } catch (Throwable t) {
        throw t;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于一个短暂而快乐的时刻,我认为已经检查过的异常最终决定已经死了,但它仍然在这方面很高兴:

void foo() {
    try {

    } catch (Throwable t) {
        Throwable t1 = t;
        throw t1;
    }
}
Run Code Online (Sandbox Code Playgroud)

try块不必为空; 它似乎可以有代码,只要该代码不会抛出已检查的异常.这似乎是合理的,但我的问题是,语言规范中的哪些规则描述了这种行为?据我所知,§14.18town语句明确禁止它,因为t表达式的类型是一个已检查的异常,并且它没有被捕获或声明被抛出.(?)

java exception throw language-lawyer checked-exceptions

16
推荐指数
2
解决办法
582
查看次数

我什么时候应该使用ThrowHelper方法而不是直接投掷?

什么时候使用ThrowHelper方法而不是直接投掷?

void MyMethod() {
    ...
    //throw new ArgumentNullException("paramName");
    ThrowArgumentNullException("paramName");
    ...
}
void ThrowArgumentNullException(string paramName) {
    throw new ArgumentNullException(paramName);
}
Run Code Online (Sandbox Code Playgroud)

我已经读过调用一个ThrowHelper方法(一个抛出异常的唯一方法)而不是直接抛出应该产生更小的字节码.

这个以及明显的封装(另一层间接)可能是不直接抛出的好理由,至少在某些情况下是这样.

无论如何,IMO的缺点也不是没有实质性的.

  • (异常)控制流程的一部分是隐藏的
  • 异常最终会产生更加神秘的堆栈跟踪
  • 编译器(2.0)不会识别ThrowHelper调用是方法的退出点,因此需要一些代码.

我有限的经验是整体设计经常变得更糟.

int MyMethod(int i) {
    switch (i) {
        case 1:
            return 1;
        default:
            ThrowMyException();
    }
    return 0; // Unreachable (but needed) code
 }
Run Code Online (Sandbox Code Playgroud)

这可能部分是个人品味的问题.无论如何,你对这个问题有什么个人指导?您是否发现将ThrowHelpers用于所有常见任务(如方法参数验证(ThrowArgumentNullException(paramName)等)是个好主意?我在这个问题上遗漏了哪些明显的东西?

顺便说一下,我试图不将此问题与验证问题混在一起,例如:

ThrowIfNameIsNullOrEmpty(name);
Run Code Online (Sandbox Code Playgroud)

c# exception throw

14
推荐指数
3
解决办法
4421
查看次数

如何使模拟对象在Google Mock中抛出异常?

使用Google Mock 1.7.0,我有一个带有方法的模拟对象,我希望它被调用,在这种情况下,模拟的方法应该抛出异常.

ObjectMock object_mock_;
EXPECT_CALL(object_mock_, method())
  .Times(1)
  .WillRepeatedly(???);
Run Code Online (Sandbox Code Playgroud)

是否存在引发异常的Google Mock操作?我没有在文档中找到它,但我怀疑到目前为止还没有人需要它.

谢谢!

c++ unit-testing exception throw googlemock

14
推荐指数
2
解决办法
1万
查看次数

向try块本地抛出一个数组

来自C++ Primer 18.1.1:

如果[thrown]表达式具有数组或函数类型,则表达式将转换为其对应的指针类型.

该程序如何产生9876543210(g ++ 5.2.0)的正确输出?

#include <iostream>
using namespace std;

int main(){

    try{
        int a[10] = {9,8,7,6,5,4,3,2,1,0};
        throw a;
    }
    catch(int* b) { for(int i = 0; i < 10; ++i) cout << *(b+i); }

}
Run Code Online (Sandbox Code Playgroud)

从引用中,throw a将创建一个类型的异常对象,int*它是指向数组的第一个元素的指针.但是a当我们退出try块并输入catch子句时,我们肯定会破坏数组元素,因为我们改变了块范围?在catch子句的持续时间内,我是否得到了误报或数组元素"单独留下"(未删除)?

c++ arrays throw c++11

14
推荐指数
3
解决办法
558
查看次数

C#:你举起或抛出一个例外吗?

我知道这可能并不重要,但我想知道什么是正确的.

如果一段代码包含某些版本的throw new SomeKindOfException().我们是否说这段代码可能引发异常?或抛出异常?

关键字是throw,所以我倾向于那个,但提出异常也被大量使用...

他们有某种不同的含义吗?他们中的一个是否与另一个有所不同?或者它只是两个词意味着完全相同的东西?

c# terminology exception raise throw

13
推荐指数
1
解决办法
6389
查看次数

投掷一个右值

考虑片段:

try {
    Foo f;
    throw std::move(f);
}
catch (Foo& f) { }
Run Code Online (Sandbox Code Playgroud)

[expr.throw]说:

异常对象的类型是通过从操作数的静态类型中删除任何顶级cv限定符并将类型从"T的数组"或"返回T的函数"调整为"指向T的指针"或"指针"来确定的.函数返回T",分别.

这将是Foo&&.然后根据[except.throw]初始化异常对象:

抛出异常copy-initializes(8.5,12.8)一个临时对象,称为异常对象.临时是一个左值,用于初始化匹配处理程序中声明的变量(15.3).如果异常对象的类型是不完整类型或指向不完整类型的指针(可能是cv-qualified),void则程序格式不正确.

这告诉我异常对象被初始化为:

Foo&& __exception_object = std::move(f);
Run Code Online (Sandbox Code Playgroud)

并且处理程序不匹配.但是,gcc和clang都会捕获此异常.那么这里的异常对象的实际类型是什么?如果Foo,为什么?

c++ throw language-lawyer c++14

13
推荐指数
1
解决办法
300
查看次数