As part of my continuing education, I have decided to go
back and try to work my way through the C# specifications from beginning to
end. The last time I tried this was with
C# 1.0, and the specification wasn’t 527 pages long, but this time I have been coding
in it for 14 years. I won’t blog each
page (you are welcome), but I will post at least once for each major section. The 5.0 specification can be downloaded from
Microsoft at http://www.microsoft.com/en-pk/download/details.aspx?id=7029.
The first section begins with an overview and history, and
then makes his already worth wild by dropping a new term on me:
component-oriented. It looks like I am
going to have to spend a bit of time upgrading my internal conceptual model
beyond ‘simple’ object-oriented methodologies to include the even more
encapsulated and self-contained component-oriented models. I haven’t been living under a rock, seriously,
so how did I miss this until now? It is
just a child of OOD and SOA where you conceptualize full sections of
functionality and bundle them into deliverable pieces.
Another important concept that is introduced in this first
section is the unified type system. This
means that all types within the language are derived from a common ancestor
(Object) allowing abstraction of any data item and manipulation of it through a
common set of manipulators. They also
have extended the available data types to include dynamic and inline data
structures (we will have fun looking under the covers at the IL generated by
these!) to allow the language more flexability.
The next sub-section of the standard document is a simple
Hello World program and a detailed dissection of it. I can’t improve on their descriptions, so I
will try a different tact. Let’s look at
the IL and generated when we compile this simple new program. I created a new console application in Visual
Studio and compiled it down to an executable.
I am going to use the free Telerik JustDecompile (http://www.telerik.com/products/decompiler.aspx)
to turn the binary file into readable code.
I will dig deeper into the differences in a later post, but for now I will leave it as an exercise for the reader. ;-)
I compiled the example hello.cs
file:
using System;
class Hello
{
static void Main() {
Console.WriteLine("Hello, World");
}
}
using both the command line
compiler (csc) and Visual Studio 2013, and the file sizes differed quite a
bit. We can look at both the
disassembled code from JustDecompile and the raw IL code from ildasm to find
out what the differences are. We can
also find out a good deal about what was implied by our terse source code. First, the disassembled code from the command
line compiled version and the Visual Studio version are the same:
using System;
internal class Hello
{
public Hello()
{
}
private static void Main()
{
Console.WriteLine("Hello, World");
}
}
They both show the addition of the keyword internal to the class definition, private to the Main function, and the inclusion of a no argument constructor for the class.
The difference is in the manifest sections associated with the executable itself. Here is the command line version:
The difference is in the manifest sections associated with the executable itself. Here is the command line version:
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
And here is the Visual Studio version:
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
[assembly: AssemblyCompany("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyProduct("HelloWorld")]
[assembly: AssemblyTitle("HelloWorld")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: CompilationRelaxations(8)]
[assembly: ComVisible(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: Guid("b78ba5b8-637a-4192-8163-f47b86be032f")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
It isn’t really much of a mystery, when you create a Console
Application project in Visual Studio, it automatically includes a file named
AssemblyInfo.cs with the following content:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HelloWorld")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HelloWorld")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b78ba5b8-637a-4192-8163-f47b86be032f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
And much of the listed information should be familiar from
the manifest information found in the Visual Studio version of the
disassembly. In fact, by removing all of
the information in the file gets us much closer to the same executable.