Chapter 1. C# 3.0 and .NET 3.5
The goal of C# 3.0 is to provide a simple, safe, modern, object-oriented, Internet-centric, high-performance language for .NET development. C# is now a fully mature language, and it draws on the lessons learned over the past three decades. In much the same way that you can see in young children the features and personalities of their parents and grandparents, you can easily see in C# the influence of Java, C++, Visual Basic (VB), and other languages, but you can also see the lessons learned since C# was first introduced.
Many of the programs in this book are written as console applications (rather than as Windows or web applications) to facilitate concentrating on features of the language instead of being distracted by the details of the user interface.
This chapter introduces both the C# language and the .NET platform, including the .NET 3.5 Framework.
The Evolution of C#
Each generation of C# has brought significant additions to the language, with a few standout features. Perhaps the most significant feature added to C# 2.0 was Generics (allowing for an enhancement to type safety when dealing with collections). If so, the most significant addition to C# 3.0 must be the addition of the Language-Integrated Query (LINQ) extensions, which add general-purpose data query extensions to C#; though that is by no means the only enhancement to C#.
Lambda expressions (anonymous delegates on steroids)
Implicitly typed local variables
Implicitly typed arrays
Automatic properties (a small gem)
The C# Language
The fundamental C# language is disarmingly simple, with fewer than 100 keywords and a dozen built-in datatypes, but it’s highly expressive when it comes to implementing modern programming concepts. C# includes all the support for structured, component-based, object-oriented programming that you expect of a modern language built on the shoulders of C++ and Java. Version 3.0 has been extended in three very important ways:
Full support for the declarative syntax of Windows Presentation Foundation (WPF; for creating rich Windows applications), Work Flow (WF), and Silverlight (for creating cross-platform, cross-browser Rich Internet Applications)
Many convenient features added to aid programmer productivity and to work and play well in Visual Studio 2008
A Tiny Bit of History
The C# language was originally developed by a small team led by two distinguished Microsoft engineers, Anders Hejlsberg and Scott Wiltamuth. Hejlsberg is also known for creating Turbo Pascal, a popular language for PC programming, and for leading the team that designed Borland Delphi, one of the first successful integrated development environments (IDEs) for client/server programming.
At the heart of any object-oriented language is its support for defining and working with classes. Classes define new types, allowing you to extend the language to better model the problem you are trying to solve. C# contains keywords for declaring new classes and their methods and properties, and for implementing encapsulation, inheritance, and polymorphism, the three pillars of object-oriented programming.
In C#, everything pertaining to a class declaration is found in the declaration itself. C# class definitions don’t require separate header files or Interface Definition Language (IDL) files. Moreover, C# supports inline documentation that simplifies the creation of online and print reference documentation for an application.
C# also supports interfaces, a means of making a contract with a class for services that the interface stipulates. In C#, a class can inherit from only a single parent, but a class can implement multiple interfaces. When it implements an interface, a C# class in effect promises to provide the functionality the interface specifies.
C# also provides support for structs, a concept whose meaning has changed significantly from C++. In C#, a struct is a restricted, lightweight type that, when instantiated, makes fewer demands on the operating system and on memory than a conventional class does. A struct can’t inherit from a class or be inherited from, but a struct can implement an interface. This book will demonstrate why I don’t consider structs terribly important in the world of Generics. The truth is that I haven’t put a struct in a program in five years, except to demonstrate how they are used.
C# provides full support of delegates: to provide invocation of methods through indirection. In other languages, such as C++, you might find similar functionality (as in pointers to member functions), but delegates are type-safe reference types that encapsulate methods with specific signatures and return types. Delegates have been extended greatly, first in C# 2.0 and again in C# 3.0, first with anonymous delegates and now with Lambda expressions, laying the groundwork for LINQ. We will cover this in depth in Chapter 13 and Chapter 15.
C# provides component-oriented features, such as properties, events, and declarative constructs (such as attributes). Component-oriented programming is supported by the storage of metadata with the code for the class. The metadata describes the class, including its methods and properties, as well as its security needs and other attributes, such as whether it can be serialized; the code contains the logic necessary to carry out its functions. A compiled class is thus a self-contained unit. Therefore, a hosting environment that knows how to read a class’ metadata and code needs no other information to make use of it. Using C# and the Common Language Runtime (CLR), it is possible to add custom metadata to a class by creating custom attributes. Likewise, it is possible to read class metadata using CLR types that support reflection.
When you compile your code, you create an assembly. An assembly is a collection of files that appear to the programmer to be a single dynamic link library (DLL) or executable (EXE). In .NET, an assembly is the basic unit of reuse, versioning, security, and deployment. The CLR provides a number of classes for manipulating assemblies.
Directly accessing memory using C++-style pointers
Keywords for bracketing such operations as unsafe
Warning the CLR garbage collector not to collect objects referenced by pointers until they are released
Here is the word on pointers: you can use them, but you don’t. They are like hand grenades. You’ll know when you need them, and until you do, you should keep the pin in them, put them in your footlocker, and try not to think about them. If you find yourself taking one out, call a friend before you pull the pin; then, run for cover.
The .NET Platform
When Microsoft announced C# in July 2000, its unveiling was part of a much larger event: the announcement of the .NET platform. The .NET platform was, in my view, an object-oriented operating system in disguise, laid on top of the existing operating system.
You can still create server-only web applications, but with AJAX, you can add client-side controls (and AJAX provides support for much more, including automatic JSON encoding and decoding). You can still create Windows Forms applications for Windows applications, but you can also create richer Windows applications using WPF, which uses a declarative syntax called XAML (explained in some detail in Chapter 18). That same XAML is used in creating WF applications, which can be used, among other things, as a business layer for your applications.
In one of the more exciting additions to the Framework, you can now use that same XAML to produce cross-platform (as of this writing, Windows, Mac, and Unix) and cross-browser (Firefox and Safari) Rich Internet Applications using Microsoft’s Silverlight.
For a full exploration of Silverlight, please see my blog at http://silverlight.net/blogs/jesseliberty, and watch for my book, Programming Silverlight (O’Reilly), due in 2008.
All of these development technologies can use C# for the programming logic; C# can be the core for all the programming you do across the board in the development of .NET applications from the Web to the desktop, from thin clients to thick, from Rich Internet Applications to web services.