我可以知道如何使我的非异常对象变为“可抛出”,以便在 try
中声明的任何局部变量|块喜欢 obj
在下面的 try 块中
try
{
SomeObject obj = new SomeObject();
}catch {}
可以越过作用域边界进入 catch{} 子句吗??我想用
obj
即使其状态受到损害,catch{} 子句中的实例也是如此。这有可能吗?也许可能(?)因为 C# 编译器可能会做类似的事情(为了优化我假设?)并允许 catch 子句接收任何 System.Object 但我不能在 VS 中使用它,对于这种方法:
public void Foo()
{
try
{
}
catch(Exception ex)
{
}
try
{
}
catch
{
}
}
生成这个 IL:
.method public hidebysig instance void Foo() cil managed
{
// Code size 22 (0x16)
.maxstack 1
.locals init ([0] class [mscorlib]System.Exception ex)
IL_0000: nop
.try
{
IL_0001: nop
IL_0002: nop
IL_0003: leave.s IL_000a
} // end .try
catch [mscorlib]System.Exception
{
IL_0005: stloc.0
IL_0006: nop
IL_0007: nop
IL_0008: leave.s IL_000a
} // end handler
IL_000a: nop
.try
{
IL_000b: nop
IL_000c: nop
IL_000d: leave.s IL_0014
} // end .try
catch [mscorlib]System.Object /* <-- I want to do like this*/
{
IL_000f: pop
IL_0010: nop
IL_0011: nop
IL_0012: leave.s IL_0014
} // end handler
IL_0014: nop
IL_0015: ret
} // end of method Class::Foo
有没有办法(托管/非托管)像这样“作弊”并为
SomeObject
定义“可抛出”行为?类型,以便我可以保留从有意义的类继承的权利,而不必从异常类继承只是使对象“可抛出”?如果我喜欢这个怎么样(我目前几乎已经这样做了):
SomeObject obj = null;
try
{
obj = new SomeObject();
}catch {}
如果 obj 定义在
try
的内部或外部,性能是否会降低子句看起来它们都生成相同的本地方法(不是 try 范围)存储变量 - 你得到 .locals init ([0] class ClassLibrary.Class obj
在 IL 中,如果变量从未被初始化,那么也许它不会变慢?换句话说,如果我有 SomeObject obj = null;
在方法代码内的任何地方定义,但我从未将其初始化为 SomeObject
的实际实例,如果我的变量定义在 try/catch 范围内或全局到整个函数范围(不在 try/catch 内),这是否重要(性能方面)?
最佳答案
(编辑:抱歉,我刚刚看到您在帖子末尾提出了这个建议。基本上这是正确的做法!)
不,你不能抛出任何不是从 Exception 派生的东西。但这无论如何都是错误的 - 只需提前声明变量:
SomeObject obj = null;
try
{
obj = new SomeObject();
// Other stuff
}
catch (IOException e) // Or whatever
{
// Now you can refer to obj
}
请注意
obj
如果在为变量分配新值之前抛出异常(例如,如果 SomeObject
构造函数抛出异常),则可能为 null。不,您不会因此而遭受任何性能问题 - 至少,如果有任何影响,它们将是微不足道的。代码最终可能会实际执行额外的分配,但实际上不存在相关的机会。
关于.net - 从异常类派生是在 C# 中创建对象 'throwable' 的唯一方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4288202/