C# in Depth

Book description

C# in Depth is designed to bring you to a new level of programming skill. It dives deeply into key C# topics—in particular the new ones. You'll learn to reuse algorithms in a type-safe way with C# 2 generics and expand the functionality of existing classes and interfaces using C# 3 extension methods. Tricky issues become clear in author Jon Skeet's crisp, easy-to-follow explanations and snappy, pragmatic examples. With this book under your belt, you will easily learn—and then master—new frameworks and platforms.



About the Technology

In programming, there's no substitute for knowing your stuff. In versions 2 and 3, C# introduces new concepts such as lambda expressions and implicit typing that make the language more flexible and give you more power. Using Language INtegrated Query (LINQ)—also new in C# 3—you can interact with data of any type directly from C#. Simply put, mastering these features will make you a more valuable C# developer.



About the Book


What's Inside
  • How and where (and why) to use the new language features
  • Backgrounder on C# 1
  • Cutting-edge best practices
  • Become comfortable and proficient with C# 2 and 3


About the Reader


About the Author

Jon Skeet has worked with C# since 2002, and has been a Microsoft C# MVP since October 2003. He has spent a great amount of time in the C# community answering questions in newsgroups as well as writing articles on the most misunderstood aspects of C# and .NET. After having read tens of thousands of questions over the years, Jon has developed a deep insight into the areas that developers have trouble with, as well as what they are trying to achieve. A keen reader of specifications, Jon aims to understand the language at the deepest level, which enables him to provide a detailed exposition of C#, including a few dark corners which can trip up the unwary developer.



Quotes
Become a C# 3 maestro!
- Fabrice Marguerie, C# MVP author of LINQ in Action

The best C# book I've ever read.
- Chris Mullins, C# MVP

Clear and concise.
- Robin Shahan, GoldMail.com

A treat!
- Anil Radhakrishna, ASP.NET MVP

Reveals C#'s powerful mysteries.
- Christopher Haupt, BuildingWebApps.com

So good, it hurts my head.
- J.D. Conley, Hive7 Inc.

Enriches the beginner, polishes the expert.
- Josh Cronemeyer, ThoughtWorks

Table of contents

  1. Copyright
    1. Dedication
  2. Foreword
  3. Preface
  4. Acknowledgments
  5. About This Book
    1. Who should read this book?
    2. Roadmap
    3. Terminology and typography
    4. Author Online and the C# in Depth website
    5. About the author
  6. About the Cover Illustration
  7. Comments from the Tech Review
  8. 1. Preparing for the journey
    1. 1. The changing face of C# development
      1. 1.1. Evolution in action: examples of code change
        1. 1.1.1. Defining the Product type
        2. 1.1.2. Sorting products by name
        3. 1.1.3. Querying collections
        4. 1.1.4. Representing an unknown price
        5. 1.1.5. LINQ and query expressions
      2. 1.2. A brief history of C# (and related technologies)
        1. 1.2.1. The world before C#
        2. 1.2.2. C# and .NET are born
        3. 1.2.3. Minor updates with .NET 1.1 and the first major step: .NET 2.0
        4. 1.2.4. “Next generation” products
        5. 1.2.5. Historical perspective and the fight for developer support
      3. 1.3. The .NET platform
        1. 1.3.1. Distinguishing between language, runtime, and libraries
          1. Language
          2. Runtime
          3. Framework Libraries
        2. 1.3.2. Untangling version number chaos
      4. 1.4. Fully functional code in snippet form
        1. 1.4.1. Snippets and their expansions
        2. 1.4.2. Introducing Snippy
      5. 1.5. Summary
    2. 2. Core foundations: building on C# 1
      1. 2.1. Delegates
        1. 2.1.1. A recipe for simple delegates
          1. Declaring the Delegate Type
          2. Finding an Appropriate Method for the Delegate Instance’s Action
          3. Creating a Delegate Instance
          4. Invoking a Delegate Instance
          5. A Complete Example and Some Motivation
        2. 2.1.2. Combining and removing delegates
        3. 2.1.3. A brief diversion into events
        4. 2.1.4. Summary of delegates
      2. 2.2. Type system characteristics
        1. 2.2.1. C#’s place in the world of type systems
          1. Static Typing vs. Dynamic Typing
          2. Explicit Typing vs. Implicit Typing
          3. Type-Safe vs. Type-Unsafe
        2. 2.2.2. When is C# 1’s type system not rich enough?
          1. Collections, Strongc and Weak
          2. Lack of Covariant Return Types
        3. 2.2.3. When does C# 1’s type system get in the way?
        4. 2.2.4. Summary of type system characteristics
      3. 2.3. Value types and reference types
        1. 2.3.1. Values and references in the real world
        2. 2.3.2. Value and reference type fundamentals
        3. 2.3.3. Dispelling myths
          1. Myth #1: “Structs are Lightweight Classes”
          2. Myth #2: “Reference Types Live on the Heap, Value Types Live on the Stack”
          3. Myth #3: “Objects are Passed by Reference in C# by Default”
        4. 2.3.4. Boxing and unboxing
        5. 2.3.5. Summary of value types and reference types
      4. 2.4. C# 2 and 3: new features on a solid base
        1. 2.4.1. Features related to delegates
        2. 2.4.2. Features related to the type system
        3. 2.4.3. Features related to value types
      5. 2.5. Summary
  9. 2. C#2: solving the issues of C#1
    1. 3. Parameterized typing with generics
      1. 3.1. Why generics are necessary
      2. 3.2. Simple generics for everyday use
        1. 3.2.1. Learning by example: a generic dictionary
        2. 3.2.2. Generic types and type parameters
        3. 3.2.3. Generic methods and reading generic declarations
      3. 3.3. Beyond the basics
        1. 3.3.1. Type constraints
          1. Reference Type Constraints
          2. Value Type Constraints
          3. Constructor Type Constraints
          4. Derivation Type Constraints
          5. Combining Constraints
        2. 3.3.2. Type inference for type arguments of generic methods
        3. 3.3.3. Implementing generics
          1. Default Value Expressions
          2. Direct Comparisons
          3. Full Comparison Example: Representing a Pair of Values
      4. 3.4. Advanced generics
        1. 3.4.1. Static fields and static constructors
        2. 3.4.2. How the JIT compiler handles generics
        3. 3.4.3. Generic iteration
        4. 3.4.4. Reflection and generics
          1. Using Typeof with Generic Types
          2. Methods and Properties of System.Type
          3. Reflecting Generic Methods
      5. 3.5. Generic collection classes in .NET 2.0
        1. 3.5.1. List<T>
          1. New Features of List<T>
          2. Features “Missing” from List<T>
        2. 3.5.2. Dictionary<TKey,TValue>
        3. 3.5.3. Queue<T> and Stack<T>
        4. 3.5.4. SortedList<TKey, TValue> and SortedDictionary<TKey,TValue>
        5. 3.5.5. LinkedList<T>
      6. 3.6. Limitations of generics in C# and other languages
        1. 3.6.1. Lack of covariance and contravariance
          1. Why Don’T Generics Support Covariance?
          2. Where Covariance Would be Useful
          3. Where Contravariance Would be Useful
        2. 3.6.2. Lack of operator constraints or a “numeric” constraint
        3. 3.6.3. Lack of generic properties, indexers, and other member types
        4. 3.6.4. Comparison with C++ templates
        5. 3.6.5. Comparison with Java generics
      7. 3.7. Summary
    2. 4. Saying nothing with nullable types
      1. 4.1. What do you do when you just don’t have a value?
        1. 4.1.1. Why value type variables can’t be null
        2. 4.1.2. Patterns for representing null values in C# 1
          1. Pattern 1: The Magic Value
          2. Pattern 2: A Reference Type Wrapper
          3. Pattern 3: An Extra Boolean Flag
      2. 4.2. System.Nullable<T> and System.Nullable
        1. 4.2.1. Introducing Nullable<T>
        2. 4.2.2. Boxing and unboxing
        3. 4.2.3. Equality of Nullable<T> instances
        4. 4.2.4. Support from the nongeneric Nullable class
      3. 4.3. C# 2’s syntactic sugar for nullable types
        1. 4.3.1. The ? modifier
        2. 4.3.2. Assigning and comparing with null
        3. 4.3.3. Nullable conversions and operators
          1. Conversions Involving Nullable Types
          2. Operators Involving Nullable Types
        4. 4.3.4. Nullable logic
        5. 4.3.5. The null coalescing operator
      4. 4.4. Novel uses of nullable types
        1. 4.4.1. Trying an operation without using output parameters
        2. 4.4.2. Painless comparisons with the null coalescing operator
      5. 4.5. Summary
    3. 5. Fast-tracked delegates
      1. 5.1. Saying goodbye to awkward delegate syntax
      2. 5.2. Method group conversions
      3. 5.3. Covariance and contravariance
      4. 5.4. Inline delegate actions with anonymous methods
        1. 5.4.1. Starting simply: acting on a parameter
        2. 5.4.2. Returning values from anonymous methods
        3. 5.4.3. Ignoring delegate parameters
      5. 5.5. Capturing variables in anonymous methods
        1. 5.5.1. Defining closures and different types of variables
        2. 5.5.2. Examining the behavior of captured variables
        3. 5.5.3. What’s the point of captured variables?
        4. 5.5.4. The extended lifetime of captured variables
        5. 5.5.5. Local variable instantiations
        6. 5.5.6. Mixtures of shared and distinct variables
        7. 5.5.7. Captured variable guidelines and summary
          1. Guidelines for Using Captured Variables
      6. 5.6. Summary
    4. 6. Implementing iterators the easy way
      1. 6.1. C#1: the pain of handwritten iterators
      2. 6.2. C#2: simple iterators with yield statements
        1. 6.2.1. Introducing iterator blocks and yield return
        2. 6.2.2. Visualizing an iterator’s workflow
        3. 6.2.3. Advanced iterator execution flow
          1. Ending an Iterator with Yield Break
          2. Execution of Finally Blocks
        4. 6.2.4. Quirks in the implementation
      3. 6.3. Real-life example: iterating over ranges
        1. 6.3.1. Iterating over the dates in a timetable
        2. 6.3.2. Scoping the Range class
        3. 6.3.3. Implementation using iterator blocks
      4. 6.4. Pseudo-synchronous code with the Concurrency and Coordination Runtime
      5. 6.5. Summary
    5. 7. Concluding C# 2: the final features
      1. 7.1. Partial types
        1. 7.1.1. Creating a type with multiple files
        2. 7.1.2. Uses of partial types
        3. 7.1.3. Partial methods—C# 3 only!
      2. 7.2. Static classes
      3. 7.3. Separate getter/setter property access
      4. 7.4. Namespace aliases
        1. 7.4.1. Qualifying namespace aliases
        2. 7.4.2. The global namespace alias
        3. 7.4.3. Extern aliases
      5. 7.5. Pragma directives
        1. 7.5.1. Warning pragmas
        2. 7.5.2. Checksum pragmas
      6. 7.6. Fixed-size buffers in unsafe code
      7. 7.7. Exposing internal members to selected assemblies
        1. 7.7.1. Friend assemblies in the simple case
        2. 7.7.2. Why use InternalsVisibleTo?
        3. 7.7.3. InternalsVisibleTo and signed assemblies
      8. 7.8. Summary
  10. 3. C# 3—revolutionizing how we code
    1. 8. Cutting fluff with a smart compiler
      1. 8.1. Automatically implemented properties
      2. 8.2. Implicit typing of local variables
        1. 8.2.1. Using var to declare a local variable
        2. 8.2.2. Restrictions on implicit typing
        3. 8.2.3. Pros and cons of implicit typing
        4. 8.2.4. Recommendations
      3. 8.3. Simplified initialization
        1. 8.3.1. Defining our sample types
        2. 8.3.2. Setting simple properties
        3. 8.3.3. Setting properties on embedded objects
        4. 8.3.4. Collection initializers
          1. Creating New Collections with Collection Initializers
          2. Populating Collections Within Other Object Initializers
        5. 8.3.5. Uses of initialization features
          1. “Constant” Collections
          2. Setting Up Unit Tests
          3. Parameter Encapsulation
          4. <Insert Your Favorite Use Here>
      4. 8.4. Implicitly typed arrays
      5. 8.5. Anonymous types
        1. 8.5.1. First encounters of the anonymous kind
        2. 8.5.2. Members of anonymous types
        3. 8.5.3. Projection initializers
        4. 8.5.4. What’s the point?
      6. 8.6. Summary
    2. 9. Lambda expressions and expression trees
      1. 9.1. Lambda expressions as delegates
        1. 9.1.1. Preliminaries: introducing the Func<...> delegate types
        2. 9.1.2. First transformation to a lambda expression
        3. 9.1.3. Using a single expression as the body
        4. 9.1.4. Implicitly typed parameter lists
        5. 9.1.5. Shortcut for a single parameter
      2. 9.2. Simple examples using List<T> and events
        1. 9.2.1. Filtering, sorting, and actions on lists
        2. 9.2.2. Logging in an event handler
      3. 9.3. Expression trees
        1. 9.3.1. Building expression trees programmatically
        2. 9.3.2. Compiling expression trees into delegates
        3. 9.3.3. Converting C# lambda expressions to expression trees
        4. 9.3.4. Expression trees at the heart of LINQ
      4. 9.4. Changes to type inference and overload resolution
        1. 9.4.1. Reasons for change: streamlining generic method calls
        2. 9.4.2. Inferred return types of anonymous functions
        3. 9.4.3. Two-phase type inference
        4. 9.4.4. Picking the right overloaded method
        5. 9.4.5. Wrapping up type inference and overload resolution
      5. 9.5. Summary
    3. 10. Extension methods
      1. 10.1. Life before extension methods
      2. 10.2. Extension method syntax
        1. 10.2.1. Declaring extension methods
        2. 10.2.2. Calling extension methods
        3. 10.2.3. How extension methods are found
        4. 10.2.4. Calling a method on a null reference
      3. 10.3. Extension methods in .NET 3.5
        1. 10.3.1. First steps with Enumerable
        2. 10.3.2. Filtering with Where, and chaining method calls together
        3. 10.3.3. Projections using the Select method and anonymous types
        4. 10.3.4. Sorting using the OrderBy method
        5. 10.3.5. Business examples involving chaining
          1. Aggregation: Summing Salaries
          2. Grouping: Counting Bugs Assigned to Developers
      4. 10.4. Usage ideas and guidelines
        1. 10.4.1. “Extending the world” and making interfaces richer
        2. 10.4.2. Fluent interfaces
        3. 10.4.3. Using extension methods sensibly
      5. 10.5. Summary
    4. 11. Query expressions and LINQ to Objects
      1. 11.1. Introducing LINQ
        1. 11.1.1. What’s in a name?
        2. 11.1.2. Fundamental concepts in LINQ
          1. Sequences
          2. Deferred Execution and Streaming
          3. Standard Query Operators
        3. 11.1.3. Defining the sample data model
      2. 11.2. Simple beginnings: selecting elements
        1. 11.2.1. Starting with a source and ending with a selection
        2. 11.2.2. Compiler translations as the basis of query expressions
        3. 11.2.3. Range variables and nontrivial projections
        4. 11.2.4. Cast, OfType, and explicitly typed range variables
      3. 11.3. Filtering and ordering a sequence
        1. 11.3.1. Filtering using a where clause
        2. 11.3.2. Degenerate query expressions
        3. 11.3.3. Ordering using an orderby clause
      4. 11.4. Let clauses and transparent identifiers
        1. 11.4.1. Introducing an intermediate computation with let
        2. 11.4.2. Transparent identifiers
      5. 11.5. Joins
        1. 11.5.1. Inner joins using join clauses
        2. 11.5.2. Group joins with join ... into clauses
        3. 11.5.3. Cross joins using multiple from clauses
      6. 11.6. Groupings and continuations
        1. 11.6.1. Grouping with the group ... by clause
        2. 11.6.2. Query continuations
      7. 11.7. Summary
    5. 12. LINQ beyond collections
      1. 12.1. LINQ to SQL
        1. 12.1.1. Creating the defect database and entities
          1. Creating the SQL Server 2005 Database Schema
          2. Creating the Entity Classes
        2. 12.1.2. Populating the database with sample data
        3. 12.1.3. Accessing the database with query expressions
          1. First Query: Finding Defects Assigned to Tim
          2. SQL Generation for a More Complex Query: A Let Clause
          3. Explicit Joins: Matching Defects with Notification Subscriptions
          4. Implicit Joins: Showing Defect Summaries and Project Names
        4. 12.1.4. Updating the database
        5. 12.1.5. LINQ to SQL summary
      2. 12.2. Translations using IQueryable and IQueryProvider
        1. 12.2.1. Introducing IQueryable<T> and related interfaces
        2. 12.2.2. Faking it: interface implementations to log calls
        3. 12.2.3. Gluing expressions together: the Queryable extension methods
        4. 12.2.4. The fake query provider in action
        5. 12.2.5. Wrapping up IQueryable
      3. 12.3. LINQ to DataSet
        1. 12.3.1. Working with untyped datasets
        2. 12.3.2. Working with typed datasets
          1. Creating the Typed Dataset with Visual Studio
          2. Populating and Querying Typed Datasets
      4. 12.4. LINQ to XML
        1. 12.4.1. XElement and XAttribute
        2. 12.4.2. Converting sample defect data into XML
        3. 12.4.3. Queries in LINQ to XML
        4. 12.4.4. LINQ to XML summary
      5. 12.5. LINQ beyond .NET 3.5
        1. 12.5.1. Third-party LINQ
          1. LINQ to Amazon
          2. LINQ to Nhibernate
          3. LINQ to Active Directory
        2. 12.5.2. Future Microsoft LINQ technologies
          1. The ADO.NET Entity Framework
          2. Parallel LINQ (PLINQ)
      6. 12.6. Summary
    6. 13. Elegant code in the new era
      1. 13.1. The changing nature of language preferences
        1. 13.1.1. A more functional emphasis
        2. 13.1.2. Static, dynamic, implicit, explicit, or a mixture?
      2. 13.2. Delegation as the new inheritance
      3. 13.3. Readability of results over implementation
      4. 13.4. Life in a parallel universe
      5. 13.5. Farewell
  11. LINQ standard query operators
    1. A.1. Aggregation
    2. A.2. Concatenation
    3. A.3. Conversion
    4. A.4. Element operations
    5. A.5. Equality operations
    6. A.6. Generation
    7. A.7. Grouping
    8. A.8. Joins
    9. A.9. Partitioning
    10. A.10. Projection
    11. A.11. Quantifiers
    12. A.12. Filtering
    13. A.13. Set-based operations
    14. A.14. Sorting

Product information

  • Title: C# in Depth
  • Author(s): Jonathan Skeet
  • Release date: April 2008
  • Publisher(s): Manning Publications
  • ISBN: 9781933988368