A Common Language Runtime, managed execution, and automatic memory management running compiled code are now the new order of the day for SQL Server 2005. I agree that programming to the CLR is a major paradigm shift for SQL programmers-especially the notion of a garbage collector doing memory housekeeeping. The .NET Framework does a lot of the work for you. The architecture that forms the foundation for managed execution is known as the Common Type System, or the CTS.
The Common Type System is the formal definition of how all types in the .NET Framework are constructed, how all types are declared and used, and how they are managed. The CTS also lays the ground rules for protecting the integrity of executing code. Generally we talk about an object model in object-oriented programming, but the Common Type System is more than just an object model.
The CTS also specifies how types-classes-are referenced, and how applications and class libraries are packaged for execution on the CLR. The CTS describes class declaration, inheritance, referencing, and type management, not so much as SQL Server idioms but rather as .NET Framework idioms. In other words, all .NET development environments must walk the same walk and talk the same talk, if they hope to be tightly integrated with the platform.
In particular the Common Type System provides the following foundations for the .NET Framework:
It provides an object-oriented model that is supported by all programming languages that have adopted the .NET Framework. In this regard it is responsible for the Common Language Specification, and how it is implemented by .NET adherents. This means you can use even COBOL to program objects for SQL Server.
It establishes the foundations and reference framework for cross-language integration, interoperation, type safety, security, and high-performance code execution.
It defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.
You could also consider the subject of assemblies and namespaces, to be discussed later in this chapter, but let’s look at the CTS object model to get our bearings and gain some perspective.
Later in this chapter you will come across references to the root of the object model, Object, and how it functions as the so-called “ultimate” object of the Framework. Figure 11–1 illustrates the model.
Figure 11–1: The CTS type model, which is the basis for the object model and hierarchy
Language interoperability is considered to be one of the Holy Grails of software development- and the .NET Framework has risen to the challenge admirably. By writing “CLS-compliant code,” you assure that the classes you construct in one language can be used as is by other languages and their respective IDEs and development tools. Imagine that-you can now create components that can be used by any language or development tool without complex COM and ActiveX interfaces and registration details, and upload them into the SQL Server CLR. To achieve the magic, the CLS requires that class and component providers only expose to consumers the features that are common to all the .NET languages.
The CLS is really a subset of the Common Type System (CTS), as I mentioned earlier. In other words, all the rules specified by the Common Type System in the runtime environment, like type safety, drive how the CLS governs compliance at the code construction and compilation levels. The CTS lays down the rules to protect the integrity of code by ensuring type safety. When the CTS was being created, the code constructs that risked type safety were excluded from the CLS. Thus your code is always checked for type safety As long as you produce CLS-compliant code, it will be verified by the CTS.
The old cliché that rules can be broken is likely to be echoed in various far-flung shops. But when you program against the specs in the CLS, you ensure language interoperability for your intended audience and then some. CLS compliance ensures that third parties can rely on your code, and you obtain the assurance that the facilities you want exposed are available across the entire spectrum of developers.
Table 11–1 provides an abridged list of software development features that must meet CLS compliance rules. The table summarizes the features that are in the CLS and indicates whether the feature applies to both developers and compilers (All) or only compilers.
Feature | Applies to | What Must Be CLS Compliant |
---|---|---|
General | All | Visibility and exposure; types that are exposed must be compliant, but global static fields and methods are not |
Naming | All | Characters and casing keywords (compilers must prevent clashing so you need to understand the use of escape characters); names and signatures must be unique. |
Types | All | Primitives (boxed types are not compliant), visibility, interface methods, closure, and constructor invocation (typed references are not compliant) |
Type members | All | Overloading, uniqueness, and conversion |
Methods | All | Accessibility and calling conventions |
Properties | All | Accessor metadata, accessor accessibility, modification, naming, and parameters. |
Events | All | Event methods and metadata, accessor accessibility, modification, naming, and parameters |
Pointers | All | Pointers are not compliant |
Interfaces | All | Signatures and modification |
Reference types (objects) | All | Construction and invocation |
Class types | All | Inheritance (all classes must inherit) from at least one compliant class |
Arrays | All | Elements, dimensions, and bounds |
Enumerations | All | Underlying types, the Flags attribute, and field members |
Exceptions | All | Must derive from the base System.Exception class |
Customer attributes | All | Value encoding |
Metadata | Compilers | Compliance marking |
Note | For more comprehensive details, see the specification for the Common Language Infrastructure in the Microsoft .NET Framework SDK. |
The CLS includes the language constructs that are needed by all developers, of all .NET languages. That may seem like a tall order, but the specification it is not very big or complex such that a .NET language will find it very difficult to support. After all, many of the languages at the source-code level are as different from each other as fish are from birds. Just take a look at Smalltalk and compare it to Pascal, or compare C# or the managed extensions of C++ to Visual Basic.
Visual Basic does things in its own peculiar way. Thus, writing Visual Basic 2005 code to achieve one end may actually produce some strange nuances when packaged and then accessed in the C# side of the house. A good example is the big difference between the way properties are implemented in Visual Basic and how they implemented in C# (see the section “Understanding Assemblies” later in this chapter). Keep in mind that the CLR for SQL Server executes a fully functional subset of assemblies, so many of the issues you will have on standard CLR will not impact SQL Server.
Here are some of the immediate benefits of the CLR in general:
Classes that were produced in one language can be inherited by classes used in other languages.
Objects instantiated from the classes of a sender written in one language can be passed to the methods of receive objects whose classes were created in other languages. The receiving objects receive your arguments and process them as if they were written in the same language as the receiver.
Exception handling, tracing, and profiling are language agnostic. In other words, you can debug across languages, and even across processes. Exceptions can be raised in an object from one language and understood by an object created in another language.
Language interop helps maximize code reuse, which is one of the founding principles of all object-oriented languages, and something we shout out loud. The interoperability is achieved by the provision of metadata in executables and class assemblies that describe the makeup of assemblies, and the intermediate stage code that is understood across the entire Framework.
Note | Components that adhere to the CLS rules and use only the features included in the CLS may be labeled as CLS-compliant components. |
Although the members of most types defined in the .NET Framework class library are CLS-compliant, some may have one or more members that are not CLS-compliant. These members are provided to enable support for non-CLS-compliant features, such as function pointers. C#, for example, can be used to access these so-called unsafe features while the architects of Visual Basic have decided to stay clear of unsafe code. The noncompliant types and members are identified as such in the reference documentation. More information about them can be found in the .NET Framework Reference. In all cases, however, a CLS-compliant alternative to a non-CLS compliant construct is available.