Pro C# 7

With .NET and .NET Core

About this book

This essential classic title provides a comprehensive foundation in the C# programming language and the frameworks it lives in. Now in its 8th edition, you’ll find all the very latest C# 7.1 and .NET 4.7 features here, along with four brand new chapters on Microsoft’s lightweight, cross-platform framework, .NET Core, up to and including .NET Core 2.0. Coverage of ASP.NET Core, Entity Framework (EF) Core, and more, sits alongside the latest updates to .NET, including Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), and ASP.NET MVC.Dive in and discover why Pro C# has been a favorite of C# developers worldwide for over 15 years. Gain a solid foundation in object-oriented development techniques, attributes and reflection, generics and collections as well as numerous advanced topics not found in other texts (such as CIL opcodes and emitting dynamic assemblies). With the help of this book you’ll have the confidence to put C# into practice and explore the .NET universe on your own terms.What You Will LearnDiscover the latest C# 7.1 features, from tuples to pattern matchingHit the ground running with Microsoft’s lightweight, open source .NET Core platform, including ASP.NET Core MVC, ASP.NET Core web services, and Entity Framework CoreFind complete coverage of XAML, .NET 4.7, and Visual Studio 2017Understand the philosophy behind .NET and the new, cross-platform alternative, .NET Core

Table of Contents

Introducing C# and the .NET Platform

Frontmatter

Microsoft’s .NET platform (and the related C# programming language) were formally introduced circa 2002 and have quickly become a mainstay of modern-day software development. As mentioned in the book’s introduction, the goal of this text is twofold. The first order of business is to provide you with a deep and detailed examination of the syntax and semantics of C#. The second (equally important) order of business is to illustrate the use of numerous .NET APIs, including database access with ADO.NET and the Entity Framework (EF), Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), and web service and web site development using ASP.NET MVC. The last part of this book covers the newest member of the .NET family, .NET Core, which is the cross-platform version of the .NET platform. As they say, the journey of a thousand miles begins with a single step; and with this I welcome you to Chapter 1.

As a C# programmer, you can choose from among numerous tools to build .NET applications. The tool (or tools) you select will be based primarily on three factors: any associated costs, the OS you are using to develop the software, and the computing platforms you are targeting. The point of this chapter is to provide a survey of the most common integrated development environments (IDEs) that support the C# language. Do understand that this chapter will not go over every single detail of each IDE; it will give you enough information to select your programming environment as you work through this text and give you a foundation to build on.

Andrew Troelsen, Philip Japikse

Core C# Programing

Frontmatter

This chapter begins your formal investigation of the C# programming language by presenting a number of bite-sized, stand-alone topics you must be comfortable with as you explore the .NET Framework. The first order of business is to understand how to build your program’s application object and to examine the composition of an executable program’s entry point: the Main() method. Next, you will investigate the fundamental C# data types (and their equivalent types in the System namespace) including an examination of the System.String and System.Text.StringBuilder classes.

This chapter picks up where Chapter 3 left off and completes your investigation of the core aspects of the C# programming language. You will start with an investigation of the details behind manipulating arrays using the syntax of C# and get to know the functionality contained within the related System.Array class type.

Andrew Troelsen, Philip Japikse

Object-Oriented Programming with C#

Frontmatter

In Chapters 3 and 4, you investigated a number of core syntactical constructs that are commonplace to any .NET application you might be developing. Here, you will begin your examination of the object-oriented capabilities of C#. The first order of business is to examine the process of building well-defined class types that support any number of constructors. After you understand the basics of defining classes and allocating objects, the remainder of this chapter will examine the role of encapsulation. Along the way, you will learn how to define class properties and come to understand the details of the static keyword, object initialization syntax, read-only fields, constant data, and partial classes.

Chapter 5 examined the first pillar of OOP: encapsulation. At that time, you learned how to build a single well-defined class type with constructors and various members (fields, properties, methods, constants, and read-only fields). This chapter will focus on the remaining two pillars of OOP: inheritance and polymorphism.

In this chapter, you will learn how to handle runtime anomalies in your C# code through the use of structured exception handling. Not only will you examine the C# keywords that allow you to handle such matters (try, catch, throw, finally, when), but you will also come to understand the distinction between application-level and system-level exceptions, as well as the role of the System.Exception base class. This discussion will lead into the topic of building custom exceptions and, finally, to a quick look at some exception-centric debugging tools of Visual Studio.

This chapter builds upon your current understanding of object-oriented development by examining the topic of interface-based programming. Here you’ll learn how to define and implement interfaces and come to understand the benefits of building types that support multiple behaviors. Along the way, you will also examine a number of related topics, such as obtaining interface references, explicit interface implementation, and the construction of interface hierarchies. You’ll also examine a number of standard interfaces defined within the .NET base class libraries. As you will see, your custom classes and structures are free to implement these predefined interfaces to support a number of useful behaviors, such as object cloning, object enumeration, and object sorting.

Andrew Troelsen, Philip Japikse

Advanced C# Programming

Frontmatter

Any application you create with the .NET platform will need to contend with the issue of maintaining and manipulating a set of data points in memory. These data points can come from any variety of locations including a relational database, a local text file, an XML document, a web service call, or perhaps user-provided input.

Up to this point in the text, most of the applications you have developed added various bits of code to Main(), which, in some way or another, sent requests to a given object. However, many applications require that an object be able to communicate back to the entity that created it using a callback mechanism. While callback mechanisms can be used in any application, they are especially critical for graphical user interfaces in that controls (such as a button) need to invoke external methods under the correct circumstances (when the button is clicked, when the mouse enters the button surface, and so forth).

In this chapter, you’ll deepen your understanding of the C# programming language by examining a number of more advanced topics. To begin, you’ll learn how to implement and use an indexer method. This C# mechanism enables you to build custom types that provide access to internal subitems using an array-like syntax. After you learn how to build an indexer method, you’ll see how to overload various operators (+, -, <, >, and so forth) and how to create custom explicit and implicit conversion routines for your types (and you’ll learn why you might want to do this).

Regardless of the type of application you are creating using the .NET platform, your program will certainly need to access some form of data as it executes. To be sure, data can be found in numerous locations, including XML files, relational databases, in-memory collections, and primitive arrays. Historically speaking, based on the location of said data, programmers needed to make use of different and unrelated APIs. The Language Integrated Query (LINQ) technology set, introduced initially in .NET 3.5, provides a concise, symmetrical, and strongly typed manner to access a wide variety of data stores. In this chapter, you will begin your investigation of LINQ by focusing on LINQ to Objects.

At this point in the book, you have learned a great deal about how to build custom class types using C#. Now you will see how the CLR manages allocated class instances (aka objects) via garbage collection. C# programmers never directly deallocate a managed object from memory (recall there is no delete keyword in the C# language). Rather, .NET objects are allocated to a region of memory termed the managed heap, where they will be automatically destroyed by the garbage collector “sometime in the future.”

Andrew Troelsen, Philip Japikse

Programming with .NET Assemblies

Frontmatter

During the first four parts of this book, you have created a number of “stand-alone” executable applications, in which all the programming logic was packaged within a single executable file (*.exe). These executable assemblies were using little more than the primary .NET class library, mscorlib.dll. While some simple .NET programs may be constructed using nothing more than the .NET base class libraries, chances are it will be commonplace for you (or your teammates) to isolate reusable programming logic into custom class libraries (*.dll files) that can be shared among applications.

As shown in Chapter 14, assemblies are the basic unit of deployment in the .NET universe. Using the integrated Object Browser of Visual Studio (and numerous other IDEs), you are able to examine the types within a project’s referenced set of assemblies. Furthermore, external tools such as ildasm.exe allow you to peek into the underlying CIL code, type metadata, and assembly manifest for a given .NET binary. In addition to this design-time investigation of .NET assemblies, you are also able to programmatically obtain this same information using the System.Reflection namespace. To this end, the first task of this chapter is to define the role of reflection and the necessity of .NET metadata.

NET 4.0 introduced a new keyword to the C# language, specifically, dynamic. This keyword allows you to incorporate scripting-like behaviors into the strongly typed world of type safety, semicolons, and curly brackets. Using this loose typing, you can greatly simplify some complex coding tasks and also gain the ability to interoperate with a number of dynamic languages which are .NET savvy.

In Chapters 14 and 15, you examined the steps taken by the CLR to resolve the location of a referenced external assembly, as well as the role of .NET metadata. In this chapter, you’ll drill deeper into the details of how an assembly is hosted by the CLR and come to understand the relationship between processes, application domains, and object contexts.

When you are building a full-scale .NET application, you will most certainly use C# (or a similar managed language such as Visual Basic), given its inherent productivity and ease of use. However, as you learned in the first chapter, the role of a managed compiler is to translate *.cs code files into terms of CIL code, type metadata, and an assembly manifest. As it turns out, CIL is a full-fledged .NET programming language, with its own syntax, semantics, and compiler (ilasm.exe).

Andrew Troelsen, Philip Japikse

Introducing the .NET Base Class Libraries

Frontmatter

Nobody enjoys working with an application that is sluggish during its execution. Moreover, nobody enjoys starting a task in an application (perhaps initiated by clicking a toolbar item) that prevents other parts of the program from being as responsive as possible. Before the release of .NET, building applications that had the ability to perform multiple tasks typically required authoring complex C++ code that used the Windows threading APIs. Thankfully, the .NET platform provides a number of ways for you to build software that can perform complex operations on unique paths of execution, with far fewer pain points.

When you create desktop applications, the ability to save information between user sessions is commonplace. This chapter examines a number of I/O-related topics as seen through the eyes of the .NET Framework. The first order of business is to explore the core types defined in the System.IO namespace and learn how to modify a machine’s directory and file structure programmatically. The next task is to explore various ways to read from and write to character-based, binary-based, string-based, and memory-based data stores.

The .NET platform defines a number of namespaces that allow you to interact with relational database systems. Collectively speaking, these namespaces are known as ADO.NET. In this chapter, you’ll learn about the overall role of ADO.NET and the core types and namespaces, and then you’ll move on to the topic of ADO.NET data providers. The .NET platform supports numerous data providers (both provided as part of the .NET Framework and available from third-party sources), each of which is optimized to communicate with a specific database management system (e.g., Microsoft SQL Server, Oracle, and MySQL).

The previous chapter examined the fundamentals of ADO.NET. ADO.NET has enabled .NET programmers to work with relational data (in a relatively straightforward manner) since the initial release of the .NET platform. However, Microsoft introduced a new component of the ADO.NET API called the Entity Framework (or simply, EF) in .NET 3.5 Service Pack 1.

Windows Communication Foundation (WCF) is the name of the API designed specifically for the process of building distributed systems. Unlike other specific distributed APIs you might have used in the past (e.g., DCOM, .NET remoting, XML web services, message queuing), WCF provides a single, unified, and extendable programming object model that you can use to interact with a number of previously diverse distributed technologies.

Andrew Troelsen, Philip Japikse

Windows Presentation Foundation

Frontmatter

When version 1.0 of the .NET platform was released, programmers who needed to build graphical desktop applications made use of two APIs named Windows Forms and GDI+, packaged up primarily in the System.Windows.Forms.dll and System.Drawing.dll assemblies. While Windows Forms/GDI+ are still viable APIs for building traditional desktop GUIs, Microsoft shipped an alternative GUI desktop API named Windows Presentation Foundation (WPF) beginning with the release of .NET 3.0.

In this chapter, you will dig into the construction of more sophisticated graphical user interfaces using several new controls and layout managers, learning about additional features of the WPF designers of Visual Studio along the way.

In this chapter, you’ll examine the graphical rendering capabilities of WPF. As you’ll see, WPF provides three separate ways to render graphical data: shapes, drawings, and visuals. After you understand the pros and cons of each approach, you will start learning about the world of interactive 2D graphics using the classes within System.Windows.Shapes. After this, you’ll see how drawings and geometries allow you to render 2D data in a more lightweight manner. Last but not least, you’ll learn how the visual layer gives you the greatest level of power and performance.

This chapter introduces you to three important (and interrelated) topics that will deepen your understanding of the Windows Presentation Foundation (WPF) API. The first order of business is to learn the role of logical resources. As you will see, the logical resource (also known as an object resource) system is a way to name and refer to commonly used objects within a WPF application. While logical resources are often authored in XAML, they can also be defined in procedural code.

This chapter will conclude your investigation of the WPF programming model by covering the capabilities that support the Model-View-ViewModel (MVVM) pattern. The first section covers observable models and observable collections. When classes and collections implement INotifyPropertyChanged and INotifyCollectionChanged (respectively), the binding manager keeps the values in the UI in sync with the bound data. Having the data in the UI accurately portray the current state of the data automatically improves the user experience significantly and reduces the manual coding required in older technologies (such as WinForms) to achieve the same result.

Andrew Troelsen, Philip Japikse

ASP.NET

Frontmatter

This chapter introduces ASP.MVC, a .NET framework for creating web applications. ASP.NET MVC grew out of the user community (specifically the ALT.NET movement) asking for a framework that more closely adhered to the tenants of HTTP, was more testable, and adhered to separation of concerns.

The previous chapter covered ASP.NET MVC, the pattern, and the .NET implementation. This chapter introduces you to the ASP.NET Web API, a service framework built largely on the chassis of MVC that shares many of the concepts, including routing, controllers, and actions.

Andrew Troelsen, Philip Japikse

.NET CORE

Frontmatter

On June 27, 2016, Microsoft announced the release of .NET Core version 1.0, a revolutionary new platform for .NET developers everywhere. This new platform was released simultaneously for Windows, OS X, and Linux, and it is based on C# and the .NET Framework that you have spent the last 30 chapters learning about. The initial release included the .NET Core runtime, ASP.NET Core, and Entity Framework Core. Since then there have been two additional releases: 1.1 and 2.0 (the current release).

Microsoft released Entity Framework Core along with .NET Core and ASP.NET Core. EF Core is a complete rewrite of EF, taking advantage of all the goodness that is .NET Core. However, being a rewrite, there wasn’t time to re-create all of the features in EF 6 within the timeline of the release of .NET Core 1.0. Based on feature comparison, the first version was, well simply put, weak. There really weren’t enough features to consider it a production-ready product.

This is the first of the two chapters that introduce ASP.NET Core. As mentioned in Chapter 31, ASP.NET MVC and ASP.NET Web API have finally been fully combined into one framework with the release of ASP.NET Core. The subtle (and some not so subtle) differences between MVC 5 and Web API are gone. Coincidentally, so are the naming differences. It is just ASP.NET Core.

The previous chapter covered ASP.NET Core in great detail while building the AutoLotMVC_Core2 web application. This chapter completes the coverage of ASP.NET Core by creating the AutoLotAPI_Core2 RESTful service.