Is output from exception classes the only way to make a throwable object in C #?

Can I somehow make my objects, without exception, become “castable”, so that any local variables declared in a try block, for example obj , in a try block below

 try { SomeObject obj = new SomeObject(); }catch {} 

can cross the border of the scope in the catch {} field. I want to use the obj instance in the catch {} clause, even if its state is compromised. Is it possible somehow?

Perhaps it is possible (?), Since the C # compiler probably does the same (for optimization, which I would suggest?), And allows the catch clause to get any System.Object, but I cannot use it 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 / unchanged) to “spoof” like this and define “rushing” behavior for SomeObject type SomeObject that I can leave my right to inherit from meaningful classes and not inherit from exception classes just make the object “catchy”?

How about if I like it (which pretty much I'm doing it now):

 SomeObject obj = null; try { obj = new SomeObject(); }catch {} 

works slower if obj is defined inside or outside the try clause, since t looks like they both generate identical local method storage variables (and not the scope of the test) - you get .locals init ([0] class ClassLibrary.Class obj in IL in anyway, so maybe it’s not slower if the variable never arises? In other words, if I have SomeObject obj = null; defined somewhere inside the method code, but I never initialize it in the actual SomeObject instance, does it matter (performance wise) if my definition is va Is ruable located inside the try / catch or global scope of the entire function (not inside try / catch)?

+4
source share
5 answers

(EDIT: Sorry, I just saw that you suggested this right at the end of your post. Basically, this is correct!)

No, you cannot throw everything that is not obtained from Exception. But in any case, it would be wrong - just declare the variable earlier:

 SomeObject obj = null; try { obj = new SomeObject(); // Other stuff } catch (IOException e) // Or whatever { // Now you can refer to obj } 

Just remember that obj can be null if a new value has been assigned before the variable (for example, if the SomeObject constructor SomeObject exception).

No, you will not experience performance problems because of this - at least if there are any effects, they will be insignificant. The code may ultimately perform an additional task, but the likelihood that this is relevant practically does not exist.

+5
source

The previous answer already recommended moving the SomeObject obj declaration to a try block. If you need to access the object above in the call stack, you can create an Exception subclass that contains a property of type SomeObject, which you can use to skip obj:

 class SomeObjectException : Exception { // Constructors here public SomeObject Object { get; set; } } 

and

 throw new SomeObjectException { Object = obj }; 
+1
source

Do you really need to worry about such performance issues? The neck of the bottle will not be your try / catch declaration or variable / initialization.

 SomeObject obj = null; try { obj = new SomeObject(); } catch (SpecificException err) { //use obj here. } 

This is the way to do it.

0
source

I do not know any other way to get rid of the Exception, for example, using the Exception. I don’t understand why you need it. Yes, I think if you place a try, operations will be lazy more.

0
source

Firstly, no, there is no way to define a variable inside a block and access it outside the block. It doesn't matter if it is a try block, a catch block, or something else. Blocks define the scope of a variable, and variables defined inside a block are tied to this level. And when something goes out of scope, it becomes suitable for garbage collection (provided that the number of links is 0, etc. Etc.).

If you need to access a variable outside the block, then what you did at the end is absolutely correct. If you use try / catch, you have more performance concerns that you worry about than declaring a variable from the outside (since the catch involves passing frames to search for a handler, etc. Etc.).

What you / can / do is throw your own custom exception with an object in the data. I would not recommend doing this, as it is not clear to me what you want to do. If you just want to clean it, just declare it outside. Or, if you are not going to do anything with the exception, for heaven's sake use the using declaration. Yes, your object should implement IDisposable , but if you have code cleanup to do there, technically you can also be.

Last thing. You said:

I want to use the obj instance in catch {}, even if its state is compromised.

Please note that there are cases where the condition may be compromised, and there is nothing hell with which you can do it. StackOverflow , ExecutionEngineException and OutOfMemoryException all come to mind. In addition, when you use a multi-threaded code, all bets are disabled if you do not block them correctly.

For quick insights into things like memory management, exception handling, etc., you can take a look at this presentation I made to debug .NET with WinDBG and SOS.

0
source

All Articles