Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Best way to re-factor
Message
From
17/02/2013 09:35:02
 
 
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
Environment versions
Environment:
C# 4.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Miscellaneous
Thread ID:
01565967
Message ID:
01566242
Views:
71
>>>
>>>Interesting - so Parse() throws exceptions all the way back up the chain - two in StringToNumber and two more in Int32 ParseInt32 ; TryParse() has none.
>>>I prefer TryParse() evne more than I did before :=}
>>
>>I remember reading about TryXXX()
>>
>>The intent is to avoid the cost of the exception
>>
>>
>>some reading
>>- http://stackoverflow.com/questions/1282252/how-much-more-expensive-is-an-exception-than-a-return-value
>>- http://blogs.msdn.com/b/ricom/archive/2003/12/19/44697.aspx
>
>Interesting reads (especially the latter). Something I was unaware of in that (if the writer is correct): 'foreach' uses a try/finally block as well as 'using' ?

To be honest - I didn't know either


Did 3 foreach tests

(1) array
(2) collection
(3) collection < T >

conclusion
(1) With the array no Try/Catch used - since the foreach simply uses an index to loop through the array. The index is compared with array.Length

(2) collection
IEnumerator is used. IEnumerator.GetEnumerator() is called
There is a try/finally. If you look at the ildasm finally code, you'll see that it tests whether the enumerator implements IDisposable.
If it does - Dispose() is called

the IEnumerator interface does not have Dispose(). So it doesn't know and has to test
http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx

(3) Collection < T >
IEnumerator < T > is used - this one implements IDisposable in addition to IEnumerator
http://msdn.microsoft.com/en-us/library/78dfe2yb.aspx

Hence uses a try/finally- but the finally block doesn't have to test whether the enumerator implements IDisposable. it knows



(1) Foreach on an array - no try used
		static void Test()
		{
			int[] aa = null;
			foreach (int x in aa)
			{
				int y = x;
			}
		}
ildasm
.method private hidebysig static void  Test() cil managed
{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init ([0] int32[] aa,
           [1] int32 x,
           [2] int32 y,
           [3] int32[] CS$6$0000,
           [4] int32 CS$7$0001,
           [5] bool CS$4$0002)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  nop
  IL_0004:  ldloc.0
  IL_0005:  stloc.3
  IL_0006:  ldc.i4.0
  IL_0007:  stloc.s    CS$7$0001
  IL_0009:  br.s       IL_001a
  IL_000b:  ldloc.3
  IL_000c:  ldloc.s    CS$7$0001
  IL_000e:  ldelem.i4
  IL_000f:  stloc.1
  IL_0010:  nop
  IL_0011:  ldloc.1
  IL_0012:  stloc.2
  IL_0013:  nop
  IL_0014:  ldloc.s    CS$7$0001
  IL_0016:  ldc.i4.1
  IL_0017:  add
  IL_0018:  stloc.s    CS$7$0001
  IL_001a:  ldloc.s    CS$7$0001
  IL_001c:  ldloc.3
  IL_001d:  ldlen
  IL_001e:  conv.i4
  IL_001f:  clt
  IL_0021:  stloc.s    CS$4$0002
  IL_0023:  ldloc.s    CS$4$0002
  IL_0025:  brtrue.s   IL_000b
  IL_0027:  ret
} // end of method OleDbTest::Test
(2) With a queue - uses try
		static void Test1()
		{
			Queue q = null;
			foreach (object  x in q)
			{
				object y = x;
			}
		}
ildasm
.method private hidebysig static void  Test1() cil managed
{
  // Code size       68 (0x44)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.Collections.Queue q,
           [1] object x,
           [2] object y,
           [3] class [mscorlib]System.Collections.IEnumerator CS$5$0000,
           [4] bool CS$4$0001,
           [5] class [mscorlib]System.IDisposable CS$0$0002)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  nop
  IL_0004:  ldloc.0
  IL_0005:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.Queue::GetEnumerator()
  IL_000a:  stloc.3
  .try
  {
    IL_000b:  br.s       IL_0018
    IL_000d:  ldloc.3
    IL_000e:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()
    IL_0013:  stloc.1
    IL_0014:  nop
    IL_0015:  ldloc.1
    IL_0016:  stloc.2
    IL_0017:  nop
    IL_0018:  ldloc.3
    IL_0019:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    IL_001e:  stloc.s    CS$4$0001
    IL_0020:  ldloc.s    CS$4$0001
    IL_0022:  brtrue.s   IL_000d
    IL_0024:  leave.s    IL_0042
  }  // end .try
  finally
  {
    IL_0026:  ldloc.3
    IL_0027:  isinst     [mscorlib]System.IDisposable
    IL_002c:  stloc.s    CS$0$0002
    IL_002e:  ldloc.s    CS$0$0002
    IL_0030:  ldnull
    IL_0031:  ceq
    IL_0033:  stloc.s    CS$4$0001
    IL_0035:  ldloc.s    CS$4$0001
    IL_0037:  brtrue.s   IL_0041
    IL_0039:  ldloc.s    CS$0$0002
    IL_003b:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0040:  nop
    IL_0041:  endfinally
  }  // end handler
  IL_0042:  nop
  IL_0043:  ret
} // end of method OleDbTest::Test1
(3) With a Queue < T > - uses Try
		static void Test2()
		{
			Queue<int> q = null;
			foreach (int x in q)
			{
				int y = x;
			}
		}
ildasm
.method private hidebysig static void  Test2() cil managed
{
  // Code size       57 (0x39)
  .maxstack  1
  .locals init ([0] class [System]System.Collections.Generic.Queue`1<int32> q,
           [1] int32 x,
           [2] int32 y,
           [3] valuetype [System]System.Collections.Generic.Queue`1/Enumerator<int32> CS$5$0000,
           [4] bool CS$4$0001)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  nop
  IL_0004:  ldloc.0
  IL_0005:  callvirt   instance valuetype [System]System.Collections.Generic.Queue`1/Enumerator<!0> class [System]System.Collections.Generic.Queue`1<int32>::GetEnumerator()
  IL_000a:  stloc.3
  .try
  {
    IL_000b:  br.s       IL_0019
    IL_000d:  ldloca.s   CS$5$0000
    IL_000f:  call       instance !0 valuetype [System]System.Collections.Generic.Queue`1/Enumerator<int32>::get_Current()
    IL_0014:  stloc.1
    IL_0015:  nop
    IL_0016:  ldloc.1
    IL_0017:  stloc.2
    IL_0018:  nop
    IL_0019:  ldloca.s   CS$5$0000
    IL_001b:  call       instance bool valuetype [System]System.Collections.Generic.Queue`1/Enumerator<int32>::MoveNext()
    IL_0020:  stloc.s    CS$4$0001
    IL_0022:  ldloc.s    CS$4$0001
    IL_0024:  brtrue.s   IL_000d
    IL_0026:  leave.s    IL_0037
  }  // end .try
  finally
  {
    IL_0028:  ldloca.s   CS$5$0000
    IL_002a:  constrained. valuetype [System]System.Collections.Generic.Queue`1/Enumerator<int32>
    IL_0030:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0035:  nop
    IL_0036:  endfinally
  }  // end handler
  IL_0037:  nop
  IL_0038:  ret
} // end of method OleDbTest::Test2
>Also I wonder if it would make sense to have an alternate 'light-weight' exception that didn't build up the stack trace info.....
Gregory
Previous
Reply
Map
View

Click here to load this message in the networking platform