Can I some how make my non-exception objects become ‘throwable’ so that any local variables declared in a try block like obj in the try block below
try
{
SomeObject obj = new SomeObject();
}catch {}
can cross the scope boundary into the catch{} clause?? I want to use the obj instance in the catch{} clause even if its state is compromised. Is this possible somehow ?
Maybe possible(?) as the C# compiler maybe doing similar (for optimization I’d assume?) and allows the catch clause to receive any System.Object but I can’t use that in VS, for this method:
public void Foo()
{
try
{
}
catch(Exception ex)
{
}
try
{
}
catch
{
}
}
generates this 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
Is there a way (managed/unmanged) to ‘cheat’ like that and define a ‘throwable’ behavior for the SomeObject type so that I can reserve my right to inherit from meaningful classes and not have to inherit from exception classes just make an object ‘throwable’ ?
How about if I do like this (which is pretty much have I do it currently):
SomeObject obj = null;
try
{
obj = new SomeObject();
}catch {}
is performance slower if obj is defineed inside or outside the try clause as t looks they are both generating identical local to the method (not the try scope) storage variable – you get .locals init ([0] class ClassLibrary.Class obj in the IL either way so maybe its not slower if the variable is never initted ? In other words if I have SomeObject obj = null; defined anywhere inside a method code but I never initialize it to an actual instance of SomeObject, does it matter (performance wise) if my varuable definition is inside the try/catch scope or global to the entire function scope(not inside try/catch) ?
(EDIT: Sorry, I’ve just seen that you suggested this right at the end of your post. Basically it’s the right thing to do!)
No, you can’t throw anything that doesn’t derive from Exception. But it would be the wrong thing to do anyway – just declare the variable earlier:
Just be aware that
objmay be null, if an exception was thrown before the variable was assigned its new value (for example if theSomeObjectconstructor threw an exception).No, you won’t suffer any performance problems due to this – at least, if there are any effects, they’ll be insignificant. The code may end up actually performing an extra assignment, but the chances of that being relevant are practically non-existent.