#915 – An Exception Can Cross Assembly Boundaries

If code within one assembly calls code within another assembly, exceptions originating within the code being called can bubble up to the calling code.  The exception can be thrown from one assembly and caught in another.

Below, code in the ConsoleApplication1 assembly calls code in the DogLibrary assembly (the Dog.Bark method).  When an exception originates in DogLibrary, we can catch it in the code running in ConsoleApplication1.

915-001

Code in ConsoleApplication1:

            try
            {
                Dog d = new Dog("Bowser");
                d.Bark(100);
            }
            catch (ApplicationException exc)
            {
                Console.WriteLine(exc.ToString());
            }

Code in DogLibrary:

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
        }

        public void Bark(int numTimes)
        {
            if (numTimes > 10)
                throw new ApplicationException("Too many times to bark");

            for (int i = 0; i < numTimes; i++)
                Console.WriteLine("Woof");
        }
    }

Catching an exception in ConsoleApplication1 that was thrown from DogLibrary:
915-002

#620 – Inherit from a Class In A Different Assembly

You can create a new class that inherits from a class that exists in another assembly (e.g. in a class library), as long as the parent class is public (and not sealed).

Let’s assume that someone gives you a copy of DogLibrary.dll, which includes two classes–a Dog class, which is defined as public and a DogMath class, which is defined as internal.

In another program, you can inherit from the Dog class, as long as you add a reference to the DogLibrary assembly.

You inherit from the Dog class just like you inherit from a class within your own program.

    public class Program
    {
        public class CrazyDog : Dog
        {
            public override void Bark()
            {
                Console.WriteLine("Grrrowfffpermuckledoodleweeeheehee!");
            }
        }

        static void Main()
        {
            CrazyDog myDog = new CrazyDog();
            myDog.Bark();
        }
    }

#180 – The CLR Loads Assemblies on Demand

When you execute a .NET program, the CLR (Common Language Runtime) loads the assembly located in the executable and then starts executing the code in the function defined as the entry point for that assembly.

If your assembly references a second assembly, that second assembly will only get loaded if its code is invoked at runtime.

This means that it makes sense to partition your application into assemblies, based on functionality and expected use.  If running a program typically only results in 20% of its code being executed, the most efficient partitioning would be to have the remaining 80% of the code in one or more assemblies other than the main assembly.  If code in one of these assemblies is never called, the assembly is never loaded.

Loading as few assemblies as possible is desirable, because this results in a smaller memory footprint for your program.

#11 – Examine IL Using Ildasm.exe

In .NET, source is compiled to an platform-neutral intermediate language called Common Intermediate Language.  The IL is later compiled into native code at runtime, running in a virtual machine.

You can examine the IL for your applications by running a tool called the IL Disassembler (ildasm.exe).  You can find ILDasm in a directory that looks something like this:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64

Alternatively, you can just type “ildasm” in the Start Menu search box in Windows 7 or Windows Vista.

ILDasm will show you three basic things:

  • A list of all classes and methods in your assembly
  • The contents of the assembly’s manifest
  • IL code for any method implemented in the assembly.

Here’s an example of what is displayed in ILDasm.