c# 4.0 unleashed - verbundzentrale des gbv · vi c#4.0 unleashed applicationdomains 37...

19
Bart De Smet C# 4.0 UNLEASHED

Upload: hadung

Post on 14-Sep-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Bart De Smet

C# 4.0UNLEASHED

Table of Contents

Introduction

Who Should Read This Book? 2

What You Need to Know Before You Read This Book 2

How This Book Is Organized 3

Part I Introduction

1 Introducing the .NET Platform 5

A Historical Perspective 5

Win32 Programming in C 6

Raising the Abstraction Level with MFC and C++ 6

Component-Driven Development with COM 7

Windows Development for the Masses in Visual Basic 7

Reaching Out to the Web with Windows DNA 8

Reaching Out to Java with J++ 8

Time for Lightning 8

A 10,000-Feet View of the .NET Platform 9

The .NET Platform 9

The Common Language Infrastructure 12

The Multilanguage Aspect of .NET 14

Introducing .NET Assemblies 15

The Common Type System Explained 17

What's Type Safety? 17

Primitive Types 19

Classes, Structures, and Enumerations 19

Interfaces 20

Delegates 21

Members 22

A Note on Generics 23

The Role of the Common Language Specification 23

Executing Managed Code 24

The Assembly Manifest 26

IL Code 27

Metadata 29

Mixing Languages 30

Diving into the Common Language Runtime 32

Bootstrapping the Runtime 33

Assembly Loading 35

vi C# 4.0 Unleashed

Application Domains 37

JIT Compilation 39

Native Image Generation 42

Automatic Memory Management 43

Exception Handling 46

Code Access Security 47

Interoperability Facilities 49

The Base Class Library 51

Summary 54

2 Introducing the C# Programming Language 55

The Evolution of C# 55

C# 1.0: Managed Code Development, Take One 56

C# 2.0: Enriching the Core Language Features 59

C# 3.0: Bridging the Gap Between Objects and Data 64

C# 4.0: Reaching Out to Dynamic Languages 76

A Sneak Peek at the Future 89

Multiparadigm 89

Language-Shaping Forces 91

Compiler as a Service 92

Taming the Concurrency Beast 94

Summary 97

3 Getting Started with .NET Development Using C# 99

Installing the .NET Framework 99

The .NET Framework Version Landscape 99

.NET Framework 4 103

Running the Installer 106

What Got Installed? 106

Your First Application: Take One 109

Writing the Code 110

Compiling It Ill

Running It 112

Inspecting Our Assembly with .NET Reflector 112

Visual Studio 2010 116

Editions 117

Expression 119

Installing Visual Studio 2010 119

A Quick Tour Through Visual Studio 2010 120

Your First Application: Take Two 124

New Project Dialog 124

Solution Explorer 126

Project Properties 127

Contents vii

Code Editor 128

Build Support 130

Debugging Support 136

Object Browser 139

Code Insight • 139

Integrated Help 144

Designers 144

Server Explorer 155

Database Mappers 157

Unit Testing I63

Team Development 167

Summary 169

Part II C#—The Language

4 Language Essentials 171

The Entry Point 171

A Trivial Console Application 171

Method Signatures 172

Allowed Entry-Point Signatures 173

Running the Sample 175

Under the Hood 176

Keywords 177

Contextual Keywords 178

Syntax Highlighting in Visual Studio 179

A Primer on Types 180

Code and Data 180

Types, Objects, and Instances 182

Variables 183

Classes and Other Types 184

Built-in Types 185

Integral Types 186

Floating-Point Types 190

The Decimal Type ..194

The Boolean Type 196

The String Type 197

Object 198

Dynamic Typing 201

A Word on CLS Compliance 202

A Matter of Style: Aliases or Not? 208

Local Variables 209

Declaration 209

Scope 210

viii C# 4.0 Unleashed

Assignment 212

Constants 213

Implicitly Typed Local Variable Declarations 215

Intermezzo on Comments 220

Single-Line Comments 220

A Primer to Preprocessing Directives 221

Delimited Comments 223

Documentation Comments 224

Arrays 228

Internal Representation 228

Single-Dimensional Arrays 229

Array Initializers 231

Jagged Arrays 233

Multidimensional Arrays 235

The Null Reference 237

What's Null Really? 237

A Common Source of Bugs 239

Nullable Value Types 240

Internal Representation 242

Use in C# 242

A Type Background 244

Summary 246

5 Expressions and Operators 247

What Are Expressions? 247

Arity of Operators 248

Precedence and Associativity 248

Evaluation of Subexpressions 250

The Evaluation Stack 251

Arithmetic Operators 255

Integer Arithmetic 255

Floating-Point Arithmetic 255

Decimal Arithmetic 258

Character Arithmetic 259

Unary Plus and Minus 260

Overflow Checking 260

Arithmetic with Nullables 265

String Concatenation 266

Shift Operators 270

Relational Operators 271

Equality for Different Types 272

Lifted Operators 273

Contents ix

Logical Operators 273

Integral Bitwise Logical Operators 273

Use for Enumerations 274

Boolean Logical Operators 275

Nullable Boolean. Logic 277

Conditional Operators 278

Under the Hood 278

An Operator's Result Type 281

Associativity 282

Null-Coalescing Operator 282

Assignment 285

Decaration Versus (Simple) Assignment 285

Compound Assignment 287

A Gentle Introduction to Definite Assignment 290

Postfix and Prefix Increment and Decrement Operators 294

Summary 297

6 A Primer on Types and Objects 299

Implicit Versus Explicit Conversions 299

Cast Expressions 300

The is Operator 306

The as Operator 311

Intermezzo: The Mythical Type Switch 315

The typeof Operator: A Sneak Peek at Reflection 317

Default Value Expression 320

Creating Objects with the new Operator 323

Behind the Scenes of Constructors 325

Object Initializers 328

Collection Initializers 333

Member Access 335

A First Look at Dynamic Typing 337

Invocation Expressions 339

Method Invocation 339

Delegate Invocation 341

Element Access 347

Summary 349

7 Simple Control Flow 351

What Are Statements, Anyway? 351

Expression Statements 353

Method Calls 353

Assignments 354

Pre- and Post-Increment/Decrement 355

x C# 4.0 Unleashed

The Empty Statement 355

Blocks 356

Declarations 357

Selection Statements 358

The if Statement 358

The switch Statement 363

Iteration Statements 376

The while Statement 376

The do.. .while Statement 380

The for Statement 381

The foreach Statement 384

A Peek at Iterators 392

Loops in the Age of Concurrency 400

The goto Statement 402

The return Statement 406

Summary 408

8 Basics of Exceptions and Resource Management 409

Exception Handling 409

Exceptions Are Objects 411

Causes of Exceptions 412

Throwing Exceptions 423

Handling Exceptions 423

The finally Clause 432

Deterministic Resource Cleanup 438

Garbage Collection in a Nutshell 438

Object Disposal 439

The using Statement 441

Implementing iDisposable 443

(In)appropriate Use of IDisposable 446

Locking on Objects 447

Under the Hood 449

The lock Statement 452

Intermezzo: Code Generation for Lock 456

Be Careful with Locks 458

Summary 462

9 Introducing Types 463

Types Revisited 463

Classes Versus Structs 466

References Versus Values 466

Heap Versus Stack 470

Contents xi

Boxing 478

The Dangers of Mutable Value Types 483

Type Members 486

Visibility 486

Static Versus Instance 490

Partial Types 496

Summary 499

10 Methods 501

Defining Methods 501

Return Type 502

Parameters 504

Value Parameters 505

Reference Parameters 508

Output Parameters 508

Parameter Arrays 510

Optional and Named Parameters 512

Overloading 516

Defining Method Overloads 517

Method Groups 518

Overload Resolution 519

Extension Methods 522

Defining Extension Methods 524

Overload Resolution 526

Using Extension Methods 527

How the Compiler Marks and Finds Extension Methods 529

Partial Methods 532

Extern Methods 536

Refactoring 537

Code Analysis 543

Summary 544

11 Fields, Properties, and Indexers 545

Fields 545

Declaring Fields 546

Accessing Fields 546

Initializing Fields 549

Read-Only Fields 553

Constants 555

Volatile Fields 557

An Intermezzo About Enums 558

Why Enums Matter 558

Underlying Types 559

xii C# 4.0 Unleashed

Assigning Values to Members 559

The System. Enum Type 561

Flags 564

Revisiting the switch Statement 568

Behind the Scenes 568

Properties 569

Declaring and Using Properties 569

Auto-Implemented Properties 572

How Properties Work 573

Indexers 574

Defining Indexers 575

How Indexers Are Implemented 577

Summary 578

12 Constructors and Finalizers 579

Constructors 579

Instance Constructors 579

Static Constructors 586

Destructors (Poorly Named Finalizers) 589

Defining Finalizers in C# 591

How Finalizers Are Run 591

How Finalizers Are Implemented 594

Disposal Before Collection: IDisposable 595

Summary 601

13 Operator Overloading and Conversions 603

Operators 603

Defining Operators 604

How Operators Are Found 605

Nullability and Lifted Operators 606

Which Operators Can Be Overloaded? 609

Implementing Equality Operations 615

How Operators Are Translated 626

Conversions 627

Built-in Conversions 627

User-Defined Conversions 631

Other Conversion Mechanisms 638

Summary 641

14 Object-Oriented Programming 643

The Cornerstones of Object Orientation 643

A Historical Perspective 643

Encapsulation 647

Contents xiii

Inheritance 648

Polymorphism 654

Types in Pictures 656

Inheritance for Classes 657

Single Inheritance for Classes 661

Multiple Inheritance for Interfaces 663

Blocking Inheritance 665

Hiding Base Class Members 666

Protected Accessibility 669

Polymorphism and Virtual Members 670

Virtual Members 671

Overriding Virtual Members 673

Declaring Virtual Members 675

Sealing and Hiding: Take Two 676

How Virtual Dispatch Works 678

How Base Calls Work 682

Abstract Classes 683

Interfaces 686

Defining Interfaces 686

Some Design Recommendations 688

Implementing Interfaces 690

Summary 694

15 Generic Types and Methods 697

Life Without Generics 697

A Real-World Example with Collections 697

Performance Worries 699

Getting Started with Generics 699

Declaring Generic Types 703

Using Generic Types 708

Performance Intermezzo 709

Operations on Type Parameters 714

Default Values 714

Getting the Type's Reflection Info Object 716

Generic Constraints 716

Interface-Based Constraints 717

Base Class Constraints 723

Default Constructor Constraint 724

Restriction to Value Types or Reference Types 731

Generic Methods 732

Co- and Contravariance 740

Annoyances with Generic Types 740

Broken Covariance for Array Types 741

xiv C# 4.0 Unleashed

Safety Guarantees 744

Generic Co- and Contravariance 746

Under the Hood 748

Where to Use 750

Summary 751

16 Collection Types 753

Nongeneric Collection Types 753

ArrayList 754

Hash Tables 755

Queue 758

Stack 759

Summary 761

Generic Collection Types 762

List<T> 762

SortedDictionary<TKey, TValue>

and SortedList<TKey, TValue> 770

Queue<T> and Stack<T> 774

Other Collection Types 775

Summary 775

17 Delegates 777

Functional Programming 777

Historical Perspective 778

Programming with Functions 779

What Are Delegates? 782

Delegate Types 782

Delegate Instances 787

Anonymous Function Expressions 789

Closures: Captured Outer

Variables 790

Lambda Expressions 795

Expression Trees 797

Invoking Delegates 799

Putting It Together: An Extensible

Calculator 803

Case Study: Delegates Used in LINQ

to Objects 807

Asynchronous Invocation 811

Combining Delegates 824

Summary 831

Contents xv

18 Events 833

The Two Sides of Delegates 834

A Reactive Application 835

Using Delegates 836

Limitations on Plain Use of Delegates 839

Using .NET Events 840

How Events Work 843

Raising Events, the Correct Way 845

Add and Remove Accessors 847

Detach Your Event Handlers 852

Recommended Event Patterns 861

EventHandler and EventArgs 862

EventHandler<T> 867

Designing Events for Use by Derived Classes 869

Case Study: INotif yProperty Interfaces and

UI Programming 871

Events in UI Frameworks 876

Countdown, the GUI Way 882

Modern Approaches to Reactive Programming 888

Events Revisited 890

Pull Versus Push 894

Dictionary Suggest Revisited 897

Summary 900

19 Language Integrated Query Essentials 901

Life Without LINQ 902

In-Memory Data 902

Relational Databases 903

XML 907

The Birth of LINQ 908

LINQ by Example 909

In-Memory Data 909

Relational Databases 911

XML 917

Query Expression Syntax 920

Why Query Expressions? 920

Getting Started 922

Source Selection Using a from Clause 923

Projection Using the Select Clause 927

Filtering Using a where Clause 933

Ordering Using the orderby Keyword 935

Grouping Using the group by Clause 942

xvi C# 4.0 Unleashed

Joining Using the j oin Clause 949

Continuing a Query Expression Using

the into Clause 955

Bindings with the let Clause 961

Summary 964

20 Language Integrated Query Internals 967

How LINQ to Objects Works 967

IEnumerable<T> and iEnumerator<T> Recap 968

LINQ to Objects Extension Methods 970

Iterators 974

Lazy Evaluation 981

How Iterators Work 984

Standard Query Operators 990

Source Generators 990

Restriction 992

Projection 997

Ordering 1002

Grouping and Joining 1003

Aggregation 1008

Predicates 1017

Set Theoretical and Sequencing

Operators 1018

Sequence Persistence 1020

Remote Versus Local with AsEnumerable 1022

The Query Pattern 1024

All About Methods 1024

Overloading Query Expression Syntax 1025

Parallel LINQ 1027

The Cost of Optimization 1028

Asparallel 1028

How PLINQ Works 1031

AsOrdered 1032

Tweaking Parallel Querying Behavior 1033

Parallel Enumeration with ForAll 1034

Expression Trees 1036

Query Expression Translation 1036

Homoiconicity for Dummies 1038

Expression Trees for Query

Expressions 1041

IQueryable<T> 1043

Summary 1046

Contents xvii

21 Reflection 1047

Typing Revisited, Static and Otherwise 1048

The Role of Metadata 1048

The Multilanguage World 1049

Taking Multilanguage to the Next Level 1051

How Does All of This Relate to C# Programming? 1052

Reflection 1054

System. Type 1054

A Primer on Application Extensibility 1059

Reflection for Methods, Properties, Events,

and More 1070

Custom Attributes 1075

Lightweight Code Generation 1082

Hello LCG 1082

A Toy Compiler for Arithmetic Expressions 1084

Expression Trees 1091

Compiler-Generated Expression Trees 1092

The Expression Tree API 1093

Using the ExpressionTreeVisitor 1105

Summary 1107

22 Dynamic Programming 1109

The dynamic Keyword in C# 4.0 1109

The dynamic Type 1111

Dynamic Typing Is Contagious 1112

Deferred Overload Resolution 1114

No System.Dynamic Type 1117

When to Use dynamic: Case Study

with IronPython 1119

DLR Internals 1127

Dynamic Call Sites and Binders 1128

Dynamic Dispatch 1134

Custom Dynamic Objects with DynamicObject 1140

A Primer to DynamicMetaObj ect 1144

Dynamic Operations 1147

Overall Architecture 1148

Office and COM Interop 1150

Essentials of COM Interop 1152

Simplified COM Interop in .NET 4 1152

Case Study: COM Interop with Excel and Word 1154

Summary 1165

xviii C# 4.0 Unleashed

23 Exceptions 1167

Life Without Exceptions 1167

Win32 1168

COM 1169

Lessons Learned 1170

Introducing Exceptions 1170

Exception Handling 1172

try Statements 1176

First-Chance Exceptions 1178

Intermezzo on Historical Debuggingwith IntelliTrace 1183

When and What to Catch 1184

Beyond Your Control 1187

Throwing Exceptions 1188

Defining Your Own Exception Types 1190

(In)famous Exception Types 1193

DivideByZeroException 1193

OvertlowException 1194

NullRef erenceException 1194

IndexOutOfRangeException 1195

InvalidCastException 1195

ArrayTypeMismatchException 1196

TypelnitializationException 1196

ObjectDisposedException 1198

OutOfMemoryException 1200

StackOverflowException 1202

ExecutionEngineException 1205

ArgumentException 1205

ArgumentNullException 1206

ArgumentOutOfRangeException 1207

InvalidOperationException 1207

NotlmplementedException 1208

NotSupportedException 1209

FormatException 1210

AggregateException 1211

Summary 1212

24 Namespaces 1213

Organizing Types in Namespaces 1213

Once Upon a Time 1214

Assemblies and Namespaces 1216

Contents xix

Declaring Namespaces 1219

Naming Conventions 1221

Visibility !221

Name Clashes Within Namespaces 1222

Importing Namespaces 1223

Name Clashes Due to Imports 1225

Using Aliases 1226

Extern Aliases 1227

Extension Methods ; 1230

Summary 1232

25 Assemblies and Application Domains 1233

Assemblies 1233

Modules and Assemblies 1234

Types of Assemblies 1236

Assembly Properties 1237

Naming, Versioning, and Deployment 1240

Strong Naming 1244

The Global Assembly Cache 1249

Referencing Assemblies 1253

How Assemblies Get Loaded at Runtime 1255

Native Image Generation (NGEN) 1261

Visibility Aspects 1265

Embedded Resources 1268

Type Forwarding 1270

Reflection Flashback 1272

Application Domains 1277

Creating Application Domains 1278

Cross-Domain Communication 1279

The Managed Add-In Framework 1287

Summary 1289

Part III Working with Base Class Libraries

26 Base Class Library Essentials 1291

The BCL: What, Where, and How? 1293

What Is Covered? 1293

Default Project References 1293

Namespaces Versus Assemblies 1294

The System and mscorlib Assemblies 1296

System.Core's Story of Red Bits and Green Bits 1298

XX C# 4.0 Unleashed

The Holy System Root Namespace 1301

Primitive Value Types 1301

Working with Arrays 1305

The Math Class 1308

Biglnteger: Beyond 32-bit and 64-bit Integers 1310

Complex Numbers 1312

Generating Random Numbers 1314

Working with Date and Time 1317

GUID Values 1325

Nullability Revisited Briefly 1327

The Uri Type 1328

Interacting with the Environment 1328

Leave the GC Alone (Most of the Time) 1334

Native Interop with IntPtr 1341

Lazy Initialization Using Lazy<T> 1343

Tuple Types 1344

Facilities to Work with Text 1346

Formatting Text 1346

Parsing Text to Objects 1352

Regular Expressions 1353

Commonly Used String Methods 1356

The StringBuilder Class 1359

Text Encoding 1361

Summary 1362

27 Diagnostics and Instrumentation 1363

Ensuring Code Quality 1364

Code Analysis 1364

Asserts and Contracts 1366

Diagnostic Debugger Output 1371

Controlling the Debugger 1373

Logging Stack Traces 1375

Measuring Performance Using Stopwatch 1376

Instrumentation 1378

Using Event Logs 1379

Monitoring with Performance Counters 1382

Other Manageability Frameworks 1385

Controlling Processes 1386

Querying Process Information 1386

Starting Processes 1387

Summary , 1389

Contents xxi

28 Working with I/O 1391

Files and Directories 1392

Listing Drives 1392

Working with Directories 1394

Working with Paths 1397

The Filelnfo Class 1398

Monitoring File System Activity 1400

Readers and Writers 1401

The File Class 1401

Textfteader and TextWriter 1406

Streams: The Bread and Butter of I/O 1408

Memory Streams 1409

Working with Files: Take Two 1410

BinaryReader and BinaryWriter 1411

Asynchronous Read and Write

Operations 1413

Streams Are Everywhere 1422

A Primer to (Named) Pipes 1423

Memory-Mapped Files in a Nutshell 1426

Overview of Other I/O Capabilities 1429

Summary 1430

29 Threading and Synchronization 1431

Using Threads 1432

Explaining the Concept of Threads 1432

The Managed Code Story 1434

Where It All Starts: The Thread Class 1436

More About a Thread's Life Cycle 1441

Managed Thread Characteristics 1446

Dealing with Exceptions 1451

Thread-Specific State • 1452

Essential Threading Debugging

Techniques 1460

Thread Pools 1463

.NET's Thread Pool 1464

Synchronization Primitives 1471

Atomicity (or Lack Thereof) Illustrated 1472

Monitors and the lock Keyword 1474

Mutexes 1477

Semaphores 1480

More Advanced Locks 1483

Signaling with Events 1486

xxii C# 4.0 Unleashed

Interlocked Helpers 1492

More Synchronization Mechanisms 1494

BackgroundWorker 1495

Summary 1499

30 Task Parallelism and Data Parallelism 1501

Pros and Cons of Threads 1502

Cutting Costs 1502

An Ideal Number of Threads? 1502

The Task Parallel Library 1503

Architecture 1503

Declarative Versus Imperative 1504

What Are Tasks? 1507

Task Parallelism I508

Creating and Starting Tasks 1508

Retrieving a Task's Result 1511

Dealing with Errors 1513

Continuations 1518

Cancellation of Tasks 1523

Parallel Invocation 1525

Waiting for Multiple Tasks 1525

How the Task Scheduler Works 1527

Data Parallelism 1529

Parallel For Loops 1529

Parallel Foreach Loops 1535

Summary 1537

Index 1539