by
kirupa | 6 February 2010
When it comes to .NET, I only write
code in C#. I only know C#. Every now and
then, though, I will find myself having to debug or
write something in Visual Basic (VB). The one minor
problem is that I actually
don't know Visual Basic. I can barely write the most
simple of commands in a code editor using the Visual
Basic syntax.
Despite me not knowing VB, I still somehow
manage. How is it possible for someone who knows
only non-VB languages to be able to figure out what
is going on in a VB project? That is where this
article comes in.
All you will need for this article is a .NET based DLL or EXE
from a project. Any
DLL or EXE is fine, though one that contains
complicated functionality will give you a better appreciation of
what you will see.
If you don't have a DLL/EXE handy, much like
lawyers, an example will be provided for you. Feel free to use
my sample project from the
following link. If you want to follow along, I
urge you to download and work with my sample project
as well.
Once you have downloaded and extracted the sample
project, open this project in Expression Blend or
Visual Studio. Inside Blend or VS, take a look at Page.xaml.cs where
some
C# code I wrote lives. You should see something
that looks as follows:
- public
partial
class
Page
:
UserControl
- {
- private
Random
seed;
-
- public
Page()
- {
- // Required to
initialize variables
-
InitializeComponent();
- }
-
- private
void
RandomizeColors(object
sender,
RoutedEventArgs
e)
- {
- seed
=
new
Random();
-
- Color0.Value
=
GetRandomColor();
- Color1.Value
=
GetRandomColor();
-
- ChangeColor.Begin();
- }
-
- private
Color
GetRandomColor()
- {
- Color
newColor
=
new
Color();
-
- newColor.A
=
(byte)255;
- newColor.R
=
(byte)seed.Next(0,
255);
- newColor.G
=
(byte)seed.Next(0,
255);
- newColor.B
=
(byte)seed.Next(0,
255);
-
- return
newColor;
- }
- }
What I will show in the next section is how to
take all of that code and see the Visual Basic
equivalent.
I should confess that the word "converting" is
probably a bit incorrect. What I am going to
describe will help you to see the Visual Basic
equivalent of C# code, but it will certainly not
convert the project for you. That is a manual
process involving a lot of copying/pasting, but it
is better than having to learn a new language
though.
First, download a copy of
redgate's free Reflector. Once you have
downloaded it, go ahead and run it. Reflector looks
basically as follows:
[ say hello to Reflector ]
Go to File | Open to launch the Open Assembly
dialog and to browse to the directory where your
application's DLL or EXE might live. If you are
using my ColorChangeTutorial example, you would go
to the Bin/Debug directory where you will see one
solitary DLL - ChangeColorTutorial.dll:
[ one is the loneliest number... ]
Select your DLL file (or EXE) and click Open.
Once you have done that, you will see that your once
empty Reflector app now displays a node containing
the name of the assembly that you just added:
[ your assembly has now been added ]
Now, keep expanding the node and any child nodes
until you start to see the structure of your
application slowly starting to evolve in front of
you. In my case, I went into the ChangeColorTutorial
namespace and expanded the Page class to
see all the various members that it contains -
such as
RandomizeColors and
GetRandomColor
that you saw in my C# example earlier:
[ a birds-eye overview of the application ]
When you hit a particular method that that you
are interested in, right click on it and select
Disassemble from the menu that appears. I am going
to right click on GetRandomColor and Disassemble
that method:
[ select Disassembly from the menu to see some magic
]
When you hit Disassemble, you may see a dialog
that looks as follows:
[ you may be asked to resolve some missing
references ]
For what we are trying to do, finding the exact
DLL is not necessary so go ahead and keep hitting
Skip until you see the code that makes up your
method appear on the right-hand side of your window
in the Disassembler section:
[ the GetRandomColor method's code is displayed ]
By default, the code you see will show up in C#.
To change it to display something in Visual Basic
(VB), click on the language drop-down in the toolbar
and select VB:
[ change the language to Visual Basic ]
Once you make the languge switch, you may see the
Assembly File Selector dialog appear a few more
times. Click Skip each time. After a few moments,
you will see your code displayed in VB in the
Disassembler pane:
[ holy batman - is this Visual Basic? ]
Isn't that pretty awesome? Here is what the
RandomizeColors method from my example looks like:
[ more Visual Basic code ]
That's all there is to it. You can now copy and
paste any of this code into a Visual Basic project
and be better off for it.
If you were paying close attention to the example
code and the screenshots I've posted, you may have
noticed that the code I wrote and the code that
shows up in the disassembler is not the same.
Here is the code that I wrote for the
GetRandomColor method:
- private
Color
GetRandomColor()
- {
- Color
newColor
=
new
Color();
-
- newColor.A
=
(byte)255;
- newColor.R
=
(byte)seed.Next(0,
255);
- newColor.G
=
(byte)seed.Next(0,
255);
- newColor.B
=
(byte)seed.Next(0,
255);
-
- return
newColor;
- }
Here is the code that gets returned by the
Disassembly action:
- private
Color
GetRandomColor()
- {
- return
new
Color
{
A
=
0xff,
R
=
(byte)
this.seed.Next(0,
0xff),
G
=
(byte)
this.seed.Next(0,
0xff),
B
=
(byte)
this.seed.Next(0,
0xff)
};
- }
The end result is exactly the same in both cases
when the application is run,
but the syntax is significantly different. The
reason has to do with what Reflector looks at when
it does a dissassembly. It is not looking at your
original source. Instead, it looks at the compiler
generated instructions that are stored in your
assembly. Using these generated instructions, the
source code gets pieced together.
That doesn't fully explain the discrepancy
though. Wouldn't the generated instructions directly
map to my code? While it seems logical to say "Yes",
the answer is actually a "No".
When the compiler generates instructions,
the end result is a highly optimized version of what
your source code may have originally contained. The
verbosity and readability of my original source is
discarded in favor of something very efficient that
still produces the same end result. It is this
optimized instruction set that Reflector uses to
generate the source code.
Most
of us learn the syntax for one or two particular
languages and call it day. We work on projects or on
teams where one language is preferred over the
other, and more than likely, that language is one
that we are familiar with.
In the rare situations where you would need to
look at another language, as long as it is either VB
or C# (or Delphi, MC++, Chrome), you can always
count on Reflector to help you out.
Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!
|