With... End With

quwiltw

Contributor
Joined
Sep 18, 2001
Messages
486
Location
Washington, D.C.
If you're accessing lots of members of one object, especially repeatedly, then having it in a With... End With clause can make it cache the memory address of the object, rather than having to treverse down the dot-seperated chain of objects on every access.
 
I was thinking that that's a compiler optimization and that the compiler should probably be smart enough to detect such a situation without having explicitly putting it in a With block. Guess Not?
 
The JIT compiler may well do this, as may the VB.NET and C# compilers, I don't know. Why not compile some equivalent code in both, and check the IL produced?

[edit]I am told that VB.NET does create a temporary variable for use in a With block[/edit]
 
I just did this and, while I'm no assembly expert, there doesn't seem to be any difference.
Code:
//000059:         Dim s1 As New SimpleTest()
  IL_0001:  newobj     instance void WithTest.SimpleTest::.ctor()
  IL_0006:  stloc.0
//000060: 
//000061:         s1.FName = "Hello"
  IL_0007:  ldloc.0
  IL_0008:  ldstr      "Hello"
  IL_000d:  callvirt   instance void WithTest.SimpleTest::set_FName(string)
  IL_0012:  nop
//000062:         s1.LName = "World"
  IL_0013:  ldloc.0
  IL_0014:  ldstr      "World"
  IL_0019:  callvirt   instance void WithTest.SimpleTest::set_LName(string)
  IL_001e:  nop
//000063:         s1.Email = "tim@mailbox"
  IL_001f:  ldloc.0
  IL_0020:  ldstr      "tim@mailbox"
  IL_0025:  callvirt   instance void WithTest.SimpleTest::set_Email(string)
  IL_002a:  nop
//000064:         s1.Phone = "88888"
  IL_002b:  ldloc.0
  IL_002c:  ldstr      "88888"
  IL_0031:  callvirt   instance void WithTest.SimpleTest::set_Phone(string)
  IL_0036:  nop
//000065: 
//000066:         With s1
  IL_0037:  ldloc.0
  IL_0038:  stloc.1
//000067:             .FName = "test"
  IL_0039:  ldloc.1
  IL_003a:  ldstr      "test"
  IL_003f:  callvirt   instance void WithTest.SimpleTest::set_FName(string)
  IL_0044:  nop
//000068:             .LName = "again"
  IL_0045:  ldloc.1
  IL_0046:  ldstr      "again"
  IL_004b:  callvirt   instance void WithTest.SimpleTest::set_LName(string)
  IL_0050:  nop
//000069:             .Email = "email"
  IL_0051:  ldloc.1
  IL_0052:  ldstr      "email"
  IL_0057:  callvirt   instance void WithTest.SimpleTest::set_Email(string)
  IL_005c:  nop
//000070:             .Phone = "9999"
  IL_005d:  ldloc.1
  IL_005e:  ldstr      "9999"
  IL_0063:  callvirt   instance void WithTest.SimpleTest::set_Phone(string)
  IL_0068:  nop
//000071: 
//000072:         End With
  IL_0069:  ldnull
  IL_006a:  stloc.1
//000073:     End Sub
  IL_006b:  nop
  IL_006c:  ret
} // end of method Form1::Button1_Click

I left the source lines in so you can see the bottom set is using the with block. No apparent difference.
 
Back
Top