You are previewing C# 5.0 Unleashed.

C# 5.0 Unleashed

Cover of C# 5.0 Unleashed by Bart De Smet Published by Sams
  1. About This eBook
  2. Title Page
  3. Copyright Page
  4. Contents at a Glance
  5. Table of Contents
  6. About the Author
  7. Acknowledgments
  8. We Want to Hear from You!
  9. Reader Services
  10. Introduction
    1. Who Should Read This Book?
    2. What You Need to Know Before You Read This Book
    3. How This Book Is Organized
  11. Chapter 1. Introducing the .NET Platform
    1. A Historical Perspective
      1. Win32 Programming in C
      2. Raising the Abstraction Level with MFC and C++
      3. Component-Driven Development with COM
      4. Windows Development for the Masses in Visual Basic
      5. Reaching Out to the Web with Windows DNA
      6. Reaching Out to Java with J++
      7. Time for Lightning
      8. Modernizing COM in Windows Runtime
    2. A 10,000-Feet View of the .NET Platform
      1. The .NET Platform
    3. The Common Language Infrastructure
    4. The Multilanguage Aspect of .NET
    5. Introducing .NET Assemblies
    6. The Common Type System Explained
      1. What’s Type Safety?
      2. Primitive Types
      3. Classes, Structures, and Enumerations
      4. Interfaces
      5. Delegates
      6. Members
      7. A Note on Generics
      8. The Role of the Common Language Specification
    7. Executing Managed Code
      1. The Assembly Manifest
      2. IL Code
      3. Metadata
      4. Mixing Languages
    8. Diving into the Common Language Runtime
      1. Bootstrapping the Runtime
      2. Assembly Loading
      3. Application Domains
      4. JIT Compilation
      5. Native Image Generation
      6. Automatic Memory Management
      7. Exception Handling
      8. Code Access Security
      9. Interoperability Facilities
    9. The Base Class Library
      1. Organization with Namespaces
      2. The History of the BCL
    10. Summary
  12. Chapter 2. Introducing the C# Programming Language
    1. The Evolution of C#
      1. C# 1.0: Managed Code Development, Take One
      2. C# 2.0: Enriching the Core Language Features
      3. C# 3.0: Bridging the Gap Between Objects and Data
      4. C# 4.0: Reaching Out to Dynamic Languages
      5. C# 5.0: Asynchronous Programming Made Easy
    2. A Sneak Peek at the Future
      1. Multiparadigm
      2. Language-Shaping Forces
      3. Compiler as a Service
      4. Taming the Concurrency Beast
    3. Summary
  13. Chapter 3. Getting Started with .NET Development Using C#
    1. Installing the .NET Framework
      1. The .NET Framework Version Landscape
      2. .NET Framework 4.5
      3. Running the Installer
      4. What Got Installed?
    2. Your First Application: Take One
      1. Writing the Code
      2. Compiling It
      3. Running It
      4. Inspecting Our Assembly with ILSpy
    3. Visual Studio 2012
      1. Editions
      2. Expression
      3. Installing Visual Studio 2012
      4. A Quick Tour Through Visual Studio 2012
    4. Your First Application: Take Two
      1. New Project Dialog
      2. Solution Explorer
      3. Project Properties
      4. Code Editor
      5. Build Support
      6. Debugging Support
      7. Object Browser
      8. Code Insight
      9. Designers
      10. Server Explorer
      11. Database Mappers
      12. Unit Testing
      13. Team Development
    5. Summary
  14. Chapter 4. Language Essentials
    1. The Entry Point
      1. A Trivial Console Application
      2. Method Signatures
      3. Allowed Entry-Point Signatures
      4. Running the Sample
      5. Under the Hood
    2. Keywords
      1. Contextual Keywords
      2. Syntax Highlighting in Visual Studio
    3. A Primer on Types
      1. Code and Data
      2. Types, Objects, and Instances
      3. Variables
      4. Classes and Other Types
    4. Built-In Types
      1. Integral Types
      2. Floating-Point Types
      3. The Decimal Type
      4. The Boolean Type
      5. The String Type
      6. Object
      7. Dynamic Typing
      8. A Word on CLS Compliance
      9. A Matter of Style: Aliases or Not?
    5. Local Variables
      1. Declaration
      2. Scope
      3. Assignment
      4. Constants
      5. Implicitly Typed Local Variable Declarations
    6. Intermezzo on Comments
      1. Single-Line Comments
      2. A Primer to Preprocessing Directives
      3. Delimited Comments
      4. Documentation Comments
    7. Arrays
      1. Internal Representation
      2. Single-Dimensional Arrays
      3. Array Initializers
      4. Jagged Arrays
      5. Multidimensional Arrays
    8. The Null Reference
      1. What’s Null Really?
      2. A Common Source of Bugs
    9. Nullable Value Types
      1. Internal Representation
      2. Use in C#
      3. A Type Background
    10. Summary
  15. Chapter 5. Expressions and Operators
    1. What Are Expressions?
      1. Arity of Operators
      2. Precedence and Associativity
      3. Evaluation of Subexpressions
    2. The Evaluation Stack
    3. Arithmetic Operators
      1. Integer Arithmetic
      2. Floating-Point Arithmetic
      3. Decimal Arithmetic
      4. Character Arithmetic
      5. Unary Plus and Minus
      6. Overflow Checking
      7. Arithmetic with Nullables
    4. String Concatenation
    5. Shift Operators
    6. Relational Operators
      1. Equality for Different Types
      2. Lifted Operators
    7. Logical Operators
      1. Integral Bitwise Logical Operators
      2. Use for Enumerations
      3. Boolean Logical Operators
      4. Nullable Boolean Logic
    8. Conditional Operators
      1. Under the Hood
    9. An Operator’s Result Type
      1. Associativity
    10. Null-Coalescing Operator
    11. Assignment
      1. Declaration Versus (Simple) Assignment
      2. Compound Assignment
      3. A Gentle Introduction to Definite Assignment
      4. Postfix and Prefix Increment and Decrement Operators
    12. Summary
  16. Chapter 6. A Primer on Types and Objects
    1. Implicit Versus Explicit Conversions
      1. Cast Expressions
      2. The is Operator
      3. The as Operator
      4. Intermezzo: The Mythical Type Switch
    2. The typeof Operator: A Sneak Peek at Reflection
    3. Default Value Expression
    4. Creating Objects with the new Operator
      1. Behind the Scenes of Constructors
      2. Object Initializers
      3. Collection Initializers
    5. Member Access
      1. A First Look at Dynamic Typing
    6. Invocation Expressions
      1. Method Invocation
      2. Delegate Invocation
    7. Element Access
    8. Summary
  17. Chapter 7. Simple Control Flow
    1. What Are Statements, Anyway?
    2. Expression Statements
      1. Method Calls
      2. Assignments
      3. Pre- and Post-Increment/Decrement
    3. The Empty Statement
    4. Statement Blocks
    5. Declarations
    6. Selection Statements
      1. The if Statement
      2. The switch Statement
    7. Iteration Statements
      1. The while Statement
      2. The do...while Statement
      3. The for Statement
      4. The foreach Statement
    8. A Peek at Iterators
    9. Loops in the Age of Concurrency
    10. The goto Statement
    11. The return Statement
    12. Summary
  18. Chapter 8. Basics of Exceptions and Resource Management
    1. Exception Handling
      1. Exceptions Are Objects
      2. Causes of Exceptions
      3. Throwing Exceptions
      4. Handling Exceptions
      5. The finally Clause
    2. Deterministic Resource Cleanup
      1. Garbage Collection in a Nutshell
      2. Object Disposal
      3. The using Statement
      4. Implementing IDisposable
      5. (In)appropriate Use of IDisposable
    3. Locking on Objects
      1. Under the Hood
      2. The lock Statement
      3. Intermezzo: Code Generation for Lock
      4. Be Careful with Locks
    4. Summary
  19. Chapter 9. Introducing Types
    1. Types Revisited
    2. Classes Versus Structs
      1. References Versus Values
      2. Heap Versus Stack
      3. Boxing
      4. The Dangers of Mutable Value Types
    3. Type Members
      1. Visibility
      2. Static Versus Instance
      3. Partial Types
    4. Summary
  20. Chapter 10. Methods
    1. Defining Methods
    2. Specifying the Return Type
    3. Declaring Parameters
      1. Value Parameters
      2. Reference Parameters
      3. Output Parameters
      4. Parameter Arrays
      5. Optional and Named Parameters
    4. Overloading
      1. Defining Method Overloads
      2. Method Groups
      3. Overload Resolution
    5. Extension Methods
      1. Defining Extension Methods
      2. Overload Resolution
      3. Using Extension Methods
      4. How the Compiler Marks and Finds Extension Methods
    6. Partial Methods
    7. Extern Methods
    8. Refactoring
    9. Code Analysis
    10. Summary
  21. Chapter 11. Fields, Properties, and Indexers
    1. Fields
      1. Declaring Fields
      2. Accessing Fields
      3. Initializing Fields
      4. Read-Only Fields
      5. Constants
      6. Volatile Fields
    2. An Intermezzo About Enums
      1. Why Enums Matter
      2. Underlying Types
      3. Assigning Values to Members
      4. The System.Enum Type
      5. Flags
      6. Revisiting the switch Statement
      7. Behind the Scenes
    3. Properties
      1. Declaring and Using Properties
      2. Auto-Implemented Properties
      3. How Properties Work
    4. Indexers
      1. Defining Indexers
      2. How Indexers Are Implemented
    5. Summary
  22. Chapter 12. Constructors and Finalizers
    1. Constructors
      1. Instance Constructors
    2. Static Constructors
    3. Destructors (Poorly Named Finalizers)
      1. Defining Finalizers in C#
      2. How Finalizers Are Run
      3. How Finalizers Are Implemented
      4. Disposal Before Collection: IDisposable
    4. Summary
  23. Chapter 13. Operator Overloading and Conversions
    1. Operators
      1. Defining Operators
      2. How Operators Are Found
      3. Nullability and Lifted Operators
      4. Which Operators Can Be Overloaded?
      5. Implementing Equality Operations
      6. The Role of the System.Object’s Equals Instance Method
      7. How Operators Are Translated
    2. Conversions
      1. Built-In Conversions
      2. User-Defined Conversions
      3. Other Conversion Mechanisms
    3. Summary
  24. Chapter 14. Object-Oriented Programming
    1. The Cornerstones of Object Orientation
      1. A Historical Perspective
      2. Encapsulation
      3. Inheritance
      4. Polymorphism
      5. Types in Pictures
    2. Inheritance for Classes
      1. Single Inheritance for Classes
      2. Multiple Inheritance for Interfaces
      3. Blocking Inheritance
      4. Hiding Base Class Members
    3. Protected Accessibility
    4. Polymorphism and Virtual Members
      1. Virtual Members
      2. Overriding Virtual Members
      3. Declaring Virtual Members
      4. Sealing and Hiding: Take Two
      5. How Virtual Dispatch Works
      6. How Base Calls Work
    5. Abstract Classes
    6. Interface Types
      1. Defining Interfaces
      2. Some Design Recommendations
      3. Implementing Interfaces
    7. Summary
  25. Chapter 15. Generic Types and Methods
    1. Life Without Generics
      1. A Real-World Example with Collections
      2. Performance Worries
    2. Getting Started with Generics
    3. Declaring Generic Types
    4. Using Generic Types
    5. Performance Intermezzo
    6. Operations on Type Parameters
      1. Default Values
      2. Getting the Type’s Reflection Info Object
    7. Generic Constraints
      1. Interface-Based Constraints
      2. Base Class Constraints
      3. Default Constructor Constraint
      4. Restriction to Value Types or Reference Types
    8. Generic Methods
    9. Co- and Contravariance
      1. Annoyances with Generic Types
      2. Broken Covariance for Array Types
      3. Safety Guarantees
      4. Generic Co- and Contravariance
      5. Under the Hood
      6. Where and When to Use Variance
    10. Summary
  26. Chapter 16. Collection Types
    1. Nongeneric Collection Types
      1. ArrayList
      2. Hash Tables
      3. Queue
      4. Stack
      5. Summary
    2. Generic Collection Types
      1. List<T>
      2. SortedDictionary<TKey, TValue>, and SortedList<TKey, TValue>
      3. Queue<T> and Stack<T>
    3. Thread-Safe Collection Types
    4. Other Collection Types
    5. Summary
  27. Chapter 17. Delegates
    1. Functional Programming
      1. Historical Perspective
      2. Programming with Functions
    2. What Are Delegates?
    3. Delegate Types
    4. Delegate Instances
      1. Anonymous Function Expressions
      2. Closures: Captured Outer Variables
      3. Lambda Expressions
      4. Expression Trees
    5. Invoking Delegates
    6. Putting It Together: An Extensible Calculator
    7. Case Study: Delegates Used in LINQ to Objects
    8. Asynchronous Invocation
    9. Combining Delegates
    10. Summary
  28. Chapter 18. Events
    1. The Two Sides of Delegates
    2. A Reactive Application
      1. Using Delegates
      2. Limitations on Plain Use of Delegates
      3. Using .NET Events
    3. How Events Work
    4. Raising Events, the Correct Way
    5. add and remove Accessors
    6. Detach Your Event Handlers
    7. Recommended Event Patterns
      1. EventHandler and EventArgs
      2. EventHandler<T>
      3. Designing Events for Use by Derived Classes
    8. Case Study: INotifyProperty Interfaces and UI Programming
      1. Events in UI Frameworks
    9. Countdown, the GUI Way
    10. Event Interoperability with WinRT
    11. Introduction to Reactive Programming
      1. Events Revisited
      2. Pull Versus Push
      3. Dictionary Suggest Revisited
    12. Summary
  29. Chapter 19. Language Integrated Query Essentials
    1. Life Without LINQ
      1. In-Memory Data
      2. Relational Databases
      3. XML
      4. The Birth of LINQ
    2. LINQ by Example
      1. In-Memory Data
      2. Relational Databases
      3. XML
    3. Query Expression Syntax
      1. Why Query Expressions?
      2. Getting Started
      3. Source Selection Using a from Clause
      4. Projection Using the Select Clause
      5. Filtering Using a where Clause
      6. Ordering Using the orderby Keyword
      7. Grouping Using the group by Clause
      8. Joining Using the join Clause
      9. Continuing a Query Expression Using the into Clause
      10. Bindings with the let Clause
    4. Summary
  30. Chapter 20. Language Integrated Query Internals
    1. How LINQ to Objects Works
      1. IEnumerable<T> and IEnumerator<T> Recap
      2. LINQ to Objects Extension Methods
      3. Iterators
      4. Lazy Evaluation
      5. How Iterators Work
    2. Standard Query Operators
      1. Source Generators
      2. Restriction
      3. Projection
      4. Ordering
      5. Grouping and Joining
      6. Aggregation
      7. Predicates
      8. Set Theoretical and Sequencing Operators
      9. Sequence Persistence
      10. Remote Versus Local with AsEnumerable
    3. The Query Pattern
      1. All About Methods
      2. Overloading Query Expression Syntax
    4. Parallel LINQ
      1. The Cost of Optimization
      2. AsParallel
      3. How PLINQ Works
      4. AsOrdered
      5. Tweaking Parallel Querying Behavior
      6. Parallel Enumeration with ForAll
    5. Expression Trees
      1. Query Expression Translation
      2. Homoiconicity for Dummies
      3. Expression Trees for Query Expressions
      4. IQueryable<T>
    6. Summary
  31. Chapter 21. Reflection
    1. Typing Revisited, Static and Otherwise
      1. The Role of Metadata
      2. The Multilanguage World
      3. Taking Multilanguage to the Next Level
      4. How Does All of This Relate to C# Programming?
    2. Reflection
      1. System.Type
      2. Discovering Types
      3. A Primer on Application Extensibility
      4. Reflection for Methods, Properties, Events, and More
      5. Custom Attributes
    3. Lightweight Code Generation
      1. Hello LCG
      2. A Toy Compiler for Arithmetic Expressions
    4. Expression Trees
      1. Compiler-Generated Expression Trees
      2. The Expression Tree API
      3. Using the ExpressionVisitor
    5. Summary
  32. Chapter 22. Dynamic Programming
    1. The dynamic Keyword in C# 4.0
      1. The dynamic Type
      2. Dynamic Typing Is Contagious
      3. Deferred Overload Resolution
      4. No System.Dynamic Type
      5. When to Use dynamic: Case Study with IronPython
    2. DLR Internals
      1. Dynamic Call Sites and Binders
      2. Dynamic Dispatch
      3. Custom Dynamic Objects with DynamicObject
      4. A Primer to DynamicMetaObject
      5. Dynamic Operations
      6. Overall Architecture
    3. Office and COM Interop
      1. Essentials of COM Interop
      2. Simplified COM Interop in .NET 4.0
      3. Case Study: COM Interop with Excel and Word
      4. Embedding of PIAs
    4. Summary
  33. Chapter 23. Exceptions
    1. Life Without Exceptions
      1. Win32
      2. COM
      3. Lessons Learned
    2. Introducing Exceptions
    3. Exception Handling
      1. try Statements
      2. First-Chance Exceptions
      3. Intermezzo on Historical Debugging with IntelliTrace
      4. When and What to Catch
      5. Beyond Your Control
    4. Throwing Exceptions
    5. Defining Your Own Exception Types
    6. (In)famous Exception Types
      1. DivideByZeroException
      2. OverflowException
      3. NullReferenceException
      4. IndexOutOfRangeException
      5. InvalidCastException
      6. ArrayTypeMismatchException
      7. TypeInitializationException
      8. OutOfMemoryException
      9. StackOverflowException
      10. ExecutionEngineException
      11. ArgumentException
      12. ArgumentNullException
      13. ArgumentOutOfRangeException
      14. InvalidOperationException
      15. NotImplementedException
      16. NotSupportedException
      17. FormatException
      18. AggregateException
    7. Summary
  34. Chapter 24. Namespaces
    1. Organizing Types in Namespaces
      1. Once Upon a Time
      2. Assemblies and Namespaces
    2. Declaring Namespaces
      1. Naming Conventions
      2. Visibility
      3. Name Clashes Within Namespaces
    3. Importing Namespaces
      1. Name Clashes Due to Imports
      2. Using Aliases
      3. Extern Aliases
      4. Extension Methods
    4. Summary
  35. Chapter 25. Assemblies and Application Domains
    1. Assemblies
      1. Modules and Assemblies
      2. Types of Assemblies
      3. Assembly Properties
      4. Naming, Versioning, and Deployment
      5. Strong Naming
      6. Strong-Name Verification at Runtime
      7. The Global Assembly Cache
      8. Referencing Assemblies
      9. How Assemblies Get Loaded at Runtime
      10. Native Image Generation
      11. Visibility Aspects
      12. Embedded Resources
      13. Type Forwarding
      14. Reflection Flashback
    2. Application Domains
      1. Creating Application Domains
      2. Cross-Domain Communication
      3. The Managed Add-In Framework
    3. Summary
  36. Chapter 26. Base Class Library Essentials
    1. The BCL: What, Where, and How?
      1. What Is Covered?
      2. Default Project References
      3. Namespaces Versus Assemblies
      4. The System and mscorlib Assemblies
      5. System.Core’s Story of Red Bits and Green Bits
    2. The Holy System Root Namespace
      1. Primitive Value Types
      2. Working with Arrays
      3. The Math Class
      4. BigInteger: Beyond 32-Bit and 64-Bit Integers
      5. Complex Numbers
      6. Generating Random Numbers
      7. Working with Date and Time
      8. GUID Values
      9. Nullability Revisited Briefly
      10. The Uri Type
      11. Interacting with the Environment
      12. Leave the GC Alone (Most of the Time)
      13. Native Interop with IntPtr
      14. Lazy Initialization Using Lazy<T>
      15. Tuple Types
    3. Facilities to Work with Text
      1. Formatting Text
      2. Parsing Text to Objects
      3. Regular Expressions
      4. Commonly Used String Methods
      5. The StringBuilder Class
      6. Text Encoding
    4. Summary
  37. Chapter 27. Diagnostics and Instrumentation
    1. Ensuring Code Quality
      1. Code Analysis
      2. Asserts and Contracts
      3. Diagnostic Debugger Output
      4. Controlling the Debugger
      5. Logging Stack Traces
      6. Measuring Performance Using Stopwatch
    2. Instrumentation
      1. Using Event Logs
      2. Monitoring with Performance Counters
      3. Other Manageability Frameworks
    3. Controlling Processes
      1. Querying Process Information
      2. Starting Processes
    4. Summary
  38. Chapter 28. Working with I/O
    1. Files and Directories
      1. Listing Drives
      2. Working with Directories
      3. Working with Paths
      4. The FileInfo Class
    2. Monitoring File System Activity
    3. Readers and Writers
      1. The File Class
      2. TextReader and TextWriter
    4. Streams: The Bread and Butter of I/O
      1. Memory Streams
      2. Working with Files: Take Two
      3. BinaryReader and BinaryWriter
      4. Asynchronous Read and Write Operations
      5. Streams Are Everywhere
    5. A Primer to (Named) Pipes
    6. Memory-Mapped Files in a Nutshell
    7. Overview of Other I/O Capabilities
    8. Summary
  39. Chapter 29. Threading and Synchronization
    1. Using Threads
      1. Explaining the Concept of Threads
      2. The Managed Code Story
      3. Where It All Starts: The Thread Class
      4. More About a Thread’s Life Cycle
      5. Managed Thread Characteristics
      6. Dealing with Exceptions
      7. Thread-Specific State
      8. Essential Threading Debugging Techniques
    2. Thread Pools
      1. .NET’s Thread Pool
    3. Synchronization Primitives
      1. Atomicity (or Lack Thereof) Illustrated
      2. Monitors and the lock Keyword
      3. Mutexes
      4. Semaphores
      5. More Advanced Locks
      6. Signaling with Events
      7. Interlocked Helpers
      8. More Synchronization Mechanisms
      9. BackgroundWorker
    4. Summary
  40. Chapter 30. Task Parallelism and Data Parallelism
    1. Pros and Cons of Threads
      1. Cutting Costs
      2. An Ideal Number of Threads?
    2. The Task Parallel Library
      1. Architecture
      2. Declarative Versus Imperative
      3. What Are Tasks?
    3. Task Parallelism
      1. Creating and Starting Tasks
      2. Retrieving a Task’s Result
      3. Dealing with Errors
      4. Continuations
      5. Cancellation of Tasks
      6. Parallel Invocation
      7. Waiting for Multiple Tasks
      8. How the Task Scheduler Works
    4. Data Parallelism
      1. Parallel For Loops
      2. Parallel ForEach Loops
    5. Summary
  41. Chapter 31. Asynchronous Programming
    1. Why Asynchronous Programming Matters
      1. It’s All About Latency
      2. What’s Asynchrony, Really?
      3. User Experience
      4. Scalability
    2. Old Asynchronous Programming Patterns
      1. Asynchronous Programming Model
      2. Event-Based Asynchronous Pattern (EAP)
      3. Task-Based Asynchronous Pattern (TAP)
      4. Method Naming and Overloading
      5. Cancellation
      6. Progress Reporting
      7. Exception Behavior
      8. Synchronization Behavior
      9. Implementing a TAP Method, Take One
      10. Key Takeaways of the TAP
    3. Asynchronous Methods and await Expressions
      1. Declaring Asynchronous Methods
      2. A Primer to await Expressions
      3. How Asynchronous Methods Execute
      4. Control Flow in Asynchronous Methods
      5. Intermezzo: Manual Callback Plumbing
      6. Synchronization Behavior of await Expressions
      7. No Asynchronous Main Method?
      8. Asynchronous Anonymous Functions
    4. Behind the Scenes
      1. The State Machine Fueling Asynchronous Methods
      2. Returning from an Asynchronous Method
      3. Exception Propagation
      4. Unwrapping AggregateExceptions
      5. Supporting Arbitrary Control Flow
      6. Saving Evaluation State with Stack Spilling
    5. Advanced Topics
      1. Building Awaitable Types
      2. Yielding Control
    6. Summary
  42. Chapter 32. Introduction to Windows Runtime
    1. What Is Windows Runtime?
      1. Hello World for Windows Store
      2. Object-Oriented and Modern COM
      3. The Windows Metadata Format
      4. Activation and IInspectable
      5. Language Projections
    2. Creating a Windows Runtime Component
      1. Writing Windows Runtime Components
      2. Building Windows Runtime Components
      3. Using Windows Runtime Components
    3. Overview of the Windows Runtime APIs
    4. Summary
  43. Index
O'Reilly logo

How Iterators Work

To wrap up our exploration of lazy execution related to iterators, let’s briefly look at how the compiler realizes iterators. We already know an iterator is a syntactical way to implement IEnumerable<T> or IEnumerator<T> automatically. The key trick is to keep track of the local state of the iterator across different calls to MoveNext.

As an example, consider the following sequence operator, which doesn’t come in LINQ out of the box. Put its definition in a static class to use it on enumerable sequences:

public static IEnumerable<T> StartWith<T>(this IEnumerable<T> tail, T head) {    yield return head;    foreach (T item in tail)        yield return item;}

This operator enables you to prepend an ...

The best content for your career. Discover unlimited learning on demand for around $1/day.