1. Trang chủ
  2. » Công Nghệ Thông Tin

CLR via C# potx

896 1,3K 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề CLR via C#
Tác giả Jeffrey Richter
Trường học Microsoft Press
Chuyên ngành Programming/Windows
Thể loại Developer Reference
Năm xuất bản 2012
Thành phố Redmond
Định dạng
Số trang 896
Dung lượng 12,21 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Discover how to: • Build, package, and deploy applications and their types • Understand how primitive, value, and reference types behave so you use them more efficiently • Use generics

Trang 1

About the Author

Jeffrey Richter is a cofounder of

Wintellect (www.wintellect.com),

a training and consulting firm dedicated to helping companies build better software faster In addition to this book’s highly regarded previous editions, he’s written several other popular titles,

including Windows via C/C++ A longtime

consultant to the Microsoft NET Framework Team, Jeff worked with Microsoft to develop

a new asynchronous programming model that’s part of NET Framework 4.5

The definitive guide to mastering CLR and NET

development—from the ground up

Dig deep and master the intricacies of the common language

runtime, C#, and NET development Led by programming expert

Jeffrey Richter, a longtime consultant to the Microsoft NET Team—

you’ll gain pragmatic insights for developing robust, reliable, and

responsive apps and components

Discover how to:

Build, package, and deploy applications and their types

Understand how primitive, value, and reference types behave

so you use them more efficiently

Use generics and interfaces to define reusable algorithms

Work effectively with special CLR types—delegates, custom

attributes, nullable types, arrays, strings

Understand how the managed heap and the garbage

collector work

Get a quick start with serialization and deserialization services

Design responsive, scalable solutions using thread pools, tasks,

cancellations, timers, and asynchronous functions

Use exception handling to assist with state management

Construct dynamically extensible apps using CLR hosting,

AppDomains, assembly loading, and reflection

Interoperate with Windows® Runtime (WinRT) components

Download from the author’s website:

http://wintellect.com/books

Jeffrey Richter

CLR via C# Fourth Edition

About the Fourth Edition

• Fully updated for Microsoft® NET Framework 4.5 and Visual Studio® 2012

• Focuses on core types in the Framework Class Library

• Expertly teaches multicore programming, generics, threading, and other essentials

• Shares practical advice from extensive insider and field experience

Trang 2

PUBLISHED BY

Microsoft Press

A Division of Microsoft Corporation

One Microsoft Way

Redmond, Washington 98052-6399

Copyright © 2012 by Jeffrey Richter

All rights reserved No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher

Library of Congress Control Number: 2012951989

ISBN: 978-0-7356-6745-7

Printed and bound in the United States of America

First Printing

Microsoft Press books are available through booksellers and distributors worldwide If you need support related

to this book, email Microsoft Press Book Support at mspinput@microsoft.com Please tell us what you think of this book at http://www.microsoft.com/learning/booksurvey

Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies All other marks are property of their respective owners

The example companies, organizations, products, domain names, email addresses, logos, people, places, and events depicted herein are fictitious No association with any real company, organization, product, domain name, email address, logo, person, place, or event is intended or should be inferred

This book expresses the author’s views and opinions The information contained in this book is provided without any express, statutory, or implied warranties Neither the authors, Microsoft Corporation, nor its resellers, or distributors will be held liable for any damages caused or alleged to be caused either directly or indirectly by this book

Acquisitions Editor: Devon Musgrave

Developmental Editor: Devon Musgrave

Project Editor: Carol Dillingham

Editorial Production: Online Training Solutions, Inc

Technical Reviewer: Christophe Nasarre; Technical Review services provided by Content Master,

a member of CM Group, Ltd

Copyeditor: Candace Sinclair

Indexer: Jan Bednarczuk

Cover: Twist Creative • Seattle

Trang 3

Kristin, words cannot express how I feel about our life together I cherish our family and all our adventures I’m filled each day with love for you.

Aidan (age 9) and Grant (age 5), you both have been an tion to me and have taught me to play and have fun Watching the two of you grow up has been so rewarding and enjoyable for

inspira-me I am lucky to be able to partake in your lives I love and preciate you more than you could ever know.

Trang 5

ap-Contents at a Glance

CHAPTER 2 Building, Packaging, Deploying, and

Administering Applications and Types 33

CHAPTER 3 Shared Assemblies and Strongly Named Assemblies 65

CHAPTER 5 Primitive, Reference, and Value Types 111

CHAPTER 14 Chars, Strings, and Working with Text 317

Trang 6

PART IV CORE FACILITIES

CHAPTER 21 The Managed Heap and Garbage Collection 505

CHAPTER 25 Interoperating with WinRT Components 643

CHAPTER 27 Compute-Bound Asynchronous Operations 691

CHAPTER 29 Primitive Thread Synchronization Constructs 757

CHAPTER 30 Hybrid Thread Synchronization Constructs 789

Index 823

Trang 7

Introduction xxiii

PART I CLR BASICS Chapter 1 The CLR’s Execution Model 3 Compiling Source Code into Managed Modules 3

Combining Managed Modules into Assemblies 6

Loading the Common Language Runtime 8

Executing Your Assembly’s Code .11

IL and Verification .16

Unsafe Code .17

The Native Code Generator Tool: NGen exe .19

The Framework Class Library .22

The Common Type System .24

The Common Language Specification .26

Interoperability with Unmanaged Code .30

Chapter 2 Building, Packaging, Deploying, and Administering Applications and Types 33 .NET Framework Deployment Goals .34

Building Types into a Module .35

Response Files 36

A Brief Look at Metadata 38

What do you think of this book? We want to hear from you!

Microsoft is interested in hearing your feedback so we can continually improve our

books and learning resources for you To participate in a brief online survey, please visit:

microsoft.com/learning/booksurvey

Trang 8

Combining Modules to Form an Assembly 45

Adding Assemblies to a Project by Using the Visual Studio IDE 51

Using the Assembly Linker 52

Adding Resource Files to an Assembly 53

Assembly Version Resource Information .54

Version Numbers 58

Culture .59

Simple Application Deployment (Privately Deployed Assemblies) .60

Simple Administrative Control (Configuration) 62

Chapter 3 Shared Assemblies and Strongly Named Assemblies 65 Two Kinds of Assemblies, Two Kinds of Deployment 66

Giving an Assembly a Strong Name 67

The Global Assembly Cache 72

Building an Assembly That References a Strongly Named Assembly 74

Strongly Named Assemblies Are Tamper-Resistant 75

Delayed Signing .76

Privately Deploying Strongly Named Assemblies 79

How the Runtime Resolves Type References 80

Advanced Administrative Control (Configuration) 83

Publisher Policy Control 86

PART II DESIGNING TYPES Chapter 4 Type Fundamentals 91 All Types Are Derived from System.Object 91

Casting Between Types 93

Casting with the C# is and as Operators 95

Namespaces and Assemblies 97

How Things Relate at Run Time 101

Trang 9

Chapter 5 Primitive, Reference, and Value Types 111

Programming Language Primitive Types 111

Checked and Unchecked Primitive Type Operations 115

Reference Types and Value Types .118

Boxing and Unboxing Value Types .124

Changing Fields in a Boxed Value Type by Using Interfaces (and Why You Shouldn’t Do This) 136

Object Equality and Identity .139

Object Hash Codes 142

The dynamic Primitive Type .144

Chapter 6 Type and Member Basics 151 The Different Kinds of Type Members .151

Type Visibility 154

Friend Assemblies .154

Member Accessibility 156

Static Classes 158

Partial Classes, Structures, and Interfaces 159

Components, Polymorphism, and Versioning 160

How the CLR Calls Virtual Methods, Properties, and Events 162

Using Type Visibility and Member Accessibility Intelligently 166

Dealing with Virtual Methods When Versioning Types 169

Chapter 7 Constants and Fields 175 Constants 175

Fields 177

Chapter 8 Methods 181 Instance Constructors and Classes (Reference Types) .181

Instance Constructors and Structures (Value Types) 184

Type Constructors 187

Trang 10

Operator Overload Methods .191

Operators and Programming Language Interoperability 193

Conversion Operator Methods 195

Extension Methods 198

Rules and Guidelines 200

Extending Various Types with Extension Methods .201

The Extension Attribute .203

Partial Methods 204

Rules and Guidelines 207

Chapter 9 Parameters 209 Optional and Named Parameters .209

Rules and Guidelines 210

The DefaultParameterValue and Optional Attributes 212

Implicitly Typed Local Variables 212

Passing Parameters by Reference to a Method 214

Passing a Variable Number of Arguments to a Method 220

Parameter and Return Type Guidelines 223

Const-ness .224

Chapter 10 Properties 227 Parameterless Properties 227

Automatically Implemented Properties 231

Defining Properties Intelligently 232

Object and Collection Initializers .235

Anonymous Types 237

The System.Tuple Type 240

Parameterful Properties 242

The Performance of Calling Property Accessor Methods 247

Property Accessor Accessibility .248

Generic Property Accessor Methods 248

Trang 11

Chapter 11 Events 249

Designing a Type That Exposes an Event 250

Step #1: Define a type that will hold any additional information that should be sent to receivers of the event notification 251

Step #2: Define the event member 252

Step #3: Define a method responsible for raising the event to notify registered objects that the event has occurred 253

Step #4: Define a method that translates the input into the desired event 256

How the Compiler Implements an Event 256

Designing a Type That Listens for an Event 258

Explicitly Implementing an Event 260

Chapter 12 Generics 265 Generics in the Framework Class Library 270

Generics Infrastructure 271

Open and Closed Types .272

Generic Types and Inheritance .274

Generic Type Identity .275

Code Explosion 277

Generic Interfaces 277

Generic Delegates 278

Delegate and Interface Contra-variant and Covariant Generic Type Arguments 279

Generic Methods 281

Generic Methods and Type Inference .283

Generics and Other Members .284

Verifiability and Constraints 284

Primary Constraints 287

Secondary Constraints .288

Constructor Constraints 289

Other Verifiability Issues 290

Trang 12

Chapter 13 Interfaces 295

Class and Interface Inheritance .296

Defining an Interface 296

Inheriting an Interface 298

More About Calling Interface Methods 300

Implicit and Explicit Interface Method Implementations (What’s Happening Behind the Scenes) .301

Generic Interfaces 303

Generics and Interface Constraints 305

Implementing Multiple Interfaces That Have the Same Method Name and Signature 307

Improving Compile-Time Type Safety with Explicit Interface Method Implementations .308

Be Careful with Explicit Interface Method Implementations .310

Design: Base Class or Interface? 312

PART III ESSENTIAL TYPES Chapter 14 Chars, Strings, and Working with Text 317 Characters .317

The System.String Type 320

Constructing Strings .320

Strings Are Immutable .323

Comparing Strings 323

String Interning 329

String Pooling 332

Examining a String’s Characters and Text Elements 333

Other String Operations 335

Constructing a String Efficiently 336

Constructing a StringBuilder Object 336

StringBuilder Members .337

Trang 13

Obtaining a String Representation of an Object: ToString 339

Specific Formats and Cultures 340

Formatting Multiple Objects into a Single String 344

Providing Your Own Custom Formatter 345

Parsing a String to Obtain an Object: Parse 348

Encodings: Converting Between Characters and Bytes 350

Encoding and Decoding Streams of Characters and Bytes .355

Base-64 String Encoding and Decoding 356

Secure Strings .357

Chapter 15 Enumerated Types and Bit Flags 361 Enumerated Types .361

Bit Flags 367

Adding Methods to Enumerated Types .371

Chapter 16 Arrays 373 Initializing Array Elements 376

Casting Arrays 378

All Arrays Are Implicitly Derived from System.Array 380

All Arrays Implicitly Implement IEnumerable, ICollection, and IList 381

Passing and Returning Arrays 382

Creating Non-Zero Lower Bound Arrays .383

Array Internals 384

Unsafe Array Access and Fixed-Size Array 388

Chapter 17 Delegates 391 A First Look at Delegates 391

Using Delegates to Call Back Static Methods .394

Using Delegates to Call Back Instance Methods 395

Trang 14

Demystifying Delegates 396

Using Delegates to Call Back Many Methods (Chaining) 400

C#’s Support for Delegate Chains 404

Having More Control over Delegate Chain Invocation 404

Enough with the Delegate Definitions Already (Generic Delegates) 407

C#’s Syntactical Sugar for Delegates 408

Syntactical Shortcut #1: No Need to Construct a Delegate Object 409

Syntactical Shortcut #2: No Need to Define a Callback Method (Lambda Expressions) 410

Syntactical Shortcut #3: No Need to Wrap Local Variables in a Class Manually to Pass Them to a Callback Method .413

Delegates and Reflection 416

Chapter 18 Custom Attributes 421 Using Custom Attributes 421

Defining Your Own Attribute Class 425

Attribute Constructor and Field/Property Data Types 428

Detecting the Use of a Custom Attribute 430

Matching Two Attribute Instances Against Each Other 434

Detecting the Use of a Custom Attribute Without Creating Attribute-Derived Objects 437

Conditional Attribute Classes 440

Chapter 19 Nullable Value Types 441 C#’s Support for Nullable Value Types 443

C#’s Null-Coalescing Operator 446

The CLR Has Special Support for Nullable Value Types 447

Boxing Nullable Value Types 447

Unboxing Nullable Value Types 448

Calling GetType via a Nullable Value Type 448

Calling Interface Methods via a Nullable Value Type .448

Trang 15

PART IV CORE FACILITIES

Chapter 20 Exceptions and State Management 451

Defining “Exception” .452

Exception-Handling Mechanics 453

The try Block 454

The catch Block 455

The finally Block 456

The System.Exception Class 460

FCL-Defined Exception Classes 463

Throwing an Exception .466

Defining Your Own Exception Class 467

Trading Reliability for Productivity .469

Guidelines and Best Practices 478

Use finally Blocks Liberally 478

Don’t Catch Everything 480

Recovering Gracefully from an Exception 481

Backing Out of a Partially Completed Operation When an Unrecoverable Exception Occurs—Maintaining State 482

Hiding an Implementation Detail to Maintain a “Contract” 483

Unhandled Exceptions 485

Debugging Exceptions 490

Exception-Handling Performance Considerations 492

Constrained Execution Regions (CERs) 494

Code Contracts 498

Chapter 21 The Managed Heap and Garbage Collection 505 Managed Heap Basics 505

Allocating Resources from the Managed Heap 506

The Garbage Collection Algorithm 507

Garbage Collections and Debugging 510

Trang 16

Generations: Improving Performance 513

Garbage Collection Triggers .519

Large Objects 519

Garbage Collection Modes 520

Forcing Garbage Collections 522

Monitoring Your Application’s Memory Usage .524

Working with Types Requiring Special Cleanup 525

Using a Type That Wraps a Native Resource 532

An Interesting Dependency Issue 537

Other GC Features for Use with Native Resources 538

Finalization Internals 542

Monitoring and Controlling the Lifetime of Objects Manually .545

Chapter 22 CLR Hosting and AppDomains 553 CLR Hosting 554

AppDomains .556

Accessing Objects Across AppDomain Boundaries 559

AppDomain Unloading 570

AppDomain Monitoring .571

AppDomain First-Chance Exception Notifications 573

How Hosts Use AppDomains 574

Executable Applications 574

Microsoft Silverlight Rich Internet Applications 574

Microsoft ASP.NET and XML Web Services Applications 575

Microsoft SQL Server 575

Your Own Imagination .576

Advanced Host Control 576

Managing the CLR by Using Managed Code 576

Writing a Robust Host Application 577

How a Host Gets Its Thread Back .578

Trang 17

Chapter 23 Assembly Loading and Reflection 583

Assembly Loading 584

Using Reflection to Build a Dynamically Extensible Application 588

Reflection Performance 589

Discovering Types Defined in an Assembly 590

What Exactly Is a Type Object? 591

Building a Hierarchy of Exception-Derived Types 593

Constructing an Instance of a Type .594

Designing an Application That Supports Add-Ins 596

Using Reflection to Discover a Type’s Members 599

Discovering a Type’s Members .599

Invoking a Type’s Members 603

Using Binding Handles to Reduce Your Process’s Memory Consumption 608

Chapter 24 Runtime Serialization 611 Serialization/Deserialization Quick Start 613

Making a Type Serializable 617

Controlling Serialization and Deserialization 619

How Formatters Serialize Type Instances 623

Controlling the Serialized/Deserialized Data 624

How to Define a Type That Implements ISerializable When the Base Type Doesn’t Implement This Interface 630

Streaming Contexts .631

Serializing a Type As a Different Type and Deserializing an Object As a Different Object 633

Serialization Surrogates 636

Surrogate Selector Chains .639

Overriding the Assembly and/or Type When Deserializing an Object 640

Trang 18

Chapter 25 Interoperating with WinRT Components 643

CLR Projections and WinRT Component Type System Rules 645

WinRT Type System Core Concepts .645

Framework Projections .649

Calling Asynchronous WinRT APIs from NET Code .649

Interoperating Between WinRT Streams and NET Streams 654

Passing Blocks of Data Between the CLR and WinRT .656

Defining WinRT Components in C# 658

PART V THREADING Chapter 26 Thread Basics 669 Why Does Windows Support Threads? 669

Thread Overhead 670

Stop the Madness 674

CPU Trends 677

CLR Threads and Windows Threads 678

Using a Dedicated Thread to Perform an Asynchronous Compute-Bound Operation .678

Reasons to Use Threads 681

Thread Scheduling and Priorities 683

Foreground Threads vs Background Threads 688

What Now? 689

Chapter 27 Compute-Bound Asynchronous Operations 691 Introducing the CLR’s Thread Pool .692

Performing a Simple Compute-Bound Operation 693

Execution Contexts 694

Cooperative Cancellation and Timeout .696

Tasks .700

Waiting for a Task to Complete and Getting Its Result 702

Canceling a Task 704

Trang 19

Starting a New Task Automatically When Another

Task Completes 705

A Task May Start Child Tasks 707

Inside a Task .707

Task Factories 709

Task Schedulers 711

Parallel’s Static For, ForEach, and Invoke Methods 713

Parallel Language Integrated Query 717

Performing a Periodic Compute-Bound Operation 720

So Many Timers, So Little Time 723

How the Thread Pool Manages Its Threads 723

Setting Thread Pool Limits 724

How Worker Threads Are Managed 724

Chapter 28 I/O-Bound Asynchronous Operations 727 How Windows Performs I/O Operations .727

C#’s Asynchronous Functions 732

How the Compiler Transforms an Async Function into a State Machine 734

Async Function Extensibility 738

Async Functions and Event Handlers .741

Async Functions in the Framework Class Library .742

Async Functions and Exception Handling .744

Other Async Function Features .745

Applications and Their Threading Models 748

Implementing a Server Asynchronously 751

Canceling I/O Operations 751

Some I/O Operations Must Be Done Synchronously 752

FileStream-Specific Issues 753

I/O Request Priorities 754

Trang 20

Chapter 29 Primitive Thread Synchronization Constructs 757

Class Libraries and Thread Safety 759

Primitive User-Mode and Kernel-Mode Constructs 760

User-Mode Constructs 762

Volatile Constructs 762

Interlocked Constructs .768

Implementing a Simple Spin Lock 773

The Interlocked Anything Pattern 776

Kernel-Mode Constructs 778

Event Constructs 782

Semaphore Constructs 784

Mutex Constructs 785

Chapter 30 Hybrid Thread Synchronization Constructs 789 A Simple Hybrid Lock 790

Spinning, Thread Ownership, and Recursion 791

Hybrid Constructs in the Framework Class Library 793

The ManualResetEventSlim and SemaphoreSlim Classes 794

The Monitor Class and Sync Blocks 794

The ReaderWriterLockSlim Class 800

The OneManyLock Class 802

The CountdownEvent Class 804

The Barrier Class 805

Thread Synchronization Construct Summary 805

The Famous Double-Check Locking Technique .807

The Condition Variable Pattern 811

Asynchronous Synchronization .814

The Concurrent Collection Classes 818

Index 823

What do you think of this book? We want to hear from you!

Microsoft is interested in hearing your feedback so we can continually improve our books and learning resources for you To participate in a brief online survey, please visit:

microsoft.com/learning/booksurvey

Trang 21

Well, here we are again Who would’ve thought? Oh, I know—I would’ve thought!

When you sign up for marriage, you really are living Groundhog Day If you

haven’t seen that movie, watch it, because you will suddenly see why you have to make

the same mistakes over and over again In this case, when Jeff said he wouldn’t write

another book, I knew it was the empty promise of an addict Jeff cannot not write

another book Just today, we were discussing another book he is absolutely not going

to write (except that there is already a chapter in progress) It is coded in his DNA A

thoroughbred is born to run and Jeff is born to write

Jeff is as predictable as the seasons He cannot stay away from the little 0s and 1s

locked inside his hard drive They cannot be ignored And while the rest of you are all

snug in your beds, Jeff’s internal alarm starts ringing around 3:00 a.m (coincidently,

when our four-year-old climbs into bed with us, another pattern I seem to have no

control over) some mysterious force compels Jeff’s brain to unlock little solutions, big

brainstorms, and frightening bugs that control him It forces him into his office to work

them out of his head The rest of us can roll over and go back to sleep, safe, knowing

that Jeff is out there somewhere solving these problems for us—like a cyber-super

hero, saving the thread from becoming just another loose end

But accruing this knowledge just for himself is not enough for Jeff He feels selfish

hoarding his insights in his little space in the universe So he must broadcast them; he

must write them down They're like radio waves hurling outward wondering if a listener

will pick them up This he does for you, dear reader; a testament to his passion for

Microsoft technologies

This book is actually adding a new layer of wisdom Jeff is getting older each time

he flies around the sun, and with the accumulation of years, he is starting to look back

Thinking about things in a more mature manner, he has rewritten the chapter

cover-ing Reflection Maybe you too will join him as he waxes poetic on this subject This is a

place where we can learn how to have the code ask about the code and really

encour-aging some deeper insights as to why Reflection works the way it does Put on your

smoking jackets, sink into a leather chair, and spend some time thinking about your

own code and its greater purpose in life

On a more lively note, there is stuff about async/await in here Apparently, this is the

progression of the AsyncEnumerator my love has been going on about for some time

Whew, I didn’t think we would ever move on from that! The thing is, as many times as

he has talked about his AsyncEnumerator, it hasn’t stuck in my mind at all I decided if

Trang 22

I knew what enumerator meant, maybe this would help me According to Wikipedia, it

is a census taker Is this chapter about census takers working out of synchronicity? That seems like a waste of taxpayer dollars Whatever it means in the computer world must

be better than that Jeff worked with the team at The Big M to perfect async/await, and now it is here in this book laid out for your reading pleasure; I suggest you read it sequentially

Another major addition to the book is the one I’m most excited about It is my expectation of you all to read and internalize this WinRT stuff This is a nerd word that somehow means: “Make Me Really Cool Apps for Some Awesome Slate Device NOW!” That’s right; the new Windows Runtime is all about awesome touch screens My kids would like some birds that fly into pigs I would like maybe something with flowers, and definitely you could use it for some educational stuff Just let your imagination go! Come up with Wonderful Innovative Nifty Really Touchy stuff Use this chapter for my benefit, please Otherwise, I may run out of patience with Jeff and his continuous book writing and lock him in a room with knitting needles and no electricity You program-mers decide: write cool apps with WinRT or no new books from Jeff!

In summary, with your continued patronage, Jeff has delivered yet another terpiece Our family can return to a more normal state Which is what, really? I think maybe normal is the book writing state

mas-Ever patiently awaiting the siren call of yet another book, Kristin Trace (Jeff’s wife)

October 2012

Help! Please save Jeff from the knitting!

Trang 23

It was October 1999 when some people at Microsoft first demonstrated the Microsoft

.NET Framework, the common language runtime (CLR), and the C# programming

language to me The moment I saw all of this, I was impressed and I knew that it was

going to change the way I wrote software in a very significant way I was asked to do

some consulting for the team and immediately agreed At first, I thought that the NET

Framework was an abstraction layer over the Win32 API and COM As I invested more

and more of my time into it, however, I realized that it was much bigger In a way, it is

its own operating system It has its own memory manager, its own security system, its

own file loader, its own error handling mechanism, its own application isolation

bound-aries (AppDomains), its own threading models, and more This book explains all these

topics (and more) so that you can effectively design and implement software

applica-tions and components for this platform

It is October 2012 as I write this text, making it 13 years now that I’ve worked with

the NET Framework and C# Over the 13 years, I have built all kinds of applications and,

as a consultant to Microsoft, have contributed quite a bit to the NET Framework itself

As a partner in my own company, Wintellect (http://Wintellect.com), I have worked with

numerous customers to help them design software, debug software, performance-tune

software, and solve issues they have with the NET Framework All these experiences

have really helped me learn the spots that people have trouble with when trying to be

productive with the NET Framework I have tried to sprinkle knowledge from these

experiences through all the topics presented in this book

Who This Book Is For

The purpose of this book is to explain how to develop applications and reusable

classes for the NET Framework Specifically, this means that I intend to explain how

the CLR works and the facilities that it offers I’ll also discuss various parts of the

Framework Class Library (FCL) No book could fully explain the FCL—it contains

liter-ally thousands of types now, and this number continues to grow at an alarming rate

Therefore, here I’m concentrating on the core types that every developer needs to be

aware of And although this book isn’t specifically about Windows Forms, Windows

Presentation Foundation (WPF), Microsoft Silverlight, XML web services, Web Forms,

Microsoft ASP.NET MVC, Windows Store Apps, and so on, the technologies presented

in the book are applicable to all these application types.

Trang 24

The book addresses Microsoft Visual Studio 2012, NET Framework 4.5, and sion 5.0 of the C# programming language Because Microsoft tries to maintain a large degree of backward compatibility when releasing a new version of these technologies, many of the things I discuss in this book apply to earlier versions as well All the code samples use the C# programming language as a way to demonstrate the behavior of the various facilities But, because the CLR is usable by many programming languages, the book’s content is still quite applicable for the non-C# programmer

ver-Note You can download the code shown in the book from Wintellect’s

web-site (http://Wintellect.com/Books).

My editors and I have worked hard to bring you the most accurate, up-to-date, in-depth, easy-to-read, painless-to-understand, bug-free information Even with this fantastic team assembled, however, things inevitably slip through the cracks If you find any mistakes in this book (especially bugs) or have some constructive feedback, I would

greatly appreciate it if you would contact me at JeffreyR@Wintellect.com

Acknowledgments

I couldn’t have written this book without the help and technical assistance of many people In particular, I’d like to thank my family The amount of time and effort that goes into writing a book is hard to measure All I know is that I could not have pro-duced this book without the support of my wife, Kristin, and my two sons, Aidan and Grant There were many times when we wanted to spend time together but were un-able to due to book obligations Now that the book project is completed, I really look forward to adventures we will all share together

For this book revision, I truly had some fantastic people helping me Several people

on the NET Framework team (many of whom I consider friends) reviewed chapters and participated in stimulating conversations with me Christophe Nasarre, who I’ve worked with on several book projects, has done just a phenomenal job of verifying my work and making sure that I’d said everything the best way it could possibly be said He has truly had a significant impact on the quality of this book As always, the Microsoft Press team is a pleasure to work with I’d like to extend a special thank you to Ben Ryan, Devon Musgrave, and Carol Dillingham Also, thanks to Susie Carr and Candace Sinclair for their editing and production support

Trang 25

Errata & Book Support

We’ve made every effort to ensure the accuracy of this book and its companion

con-tent Any errors that have been reported since this book was published are listed on our

Microsoft Press site at oreilly.com:

We Want to Hear from You

At Microsoft Press, your satisfaction is our top priority, and your feedback our most

valuable asset Please tell us what you think of this book at:

http://www.microsoft.com/learning/booksurvey

The survey is short, and we read every one of your comments and ideas Thanks in

advance for your input!

Stay in Touch

Let’s keep the conversation going! We’re on Twitter: http://twitter.com/MicrosoftPress.

Trang 27

PART I

CLR Basics

CHAPTER 1 The CLR's Execution Model 3

CHAPTER 2 Building, Packaging, Deploying, and

Administering Applications and Types .33

CHAPTER 3 Shared Assemblies and Strongly Named

Assemblies .65

Trang 29

C H A P T E R 1

The CLR’s Execution Model

In this chapter:

Compiling Source Code into Managed Modules 3

Combining Managed Modules into Assemblies 6

Loading the Common Language Runtime 8

Executing Your Assembly’s Code 11

The Native Code Generator Tool: NGen.exe 19

The Framework Class Library 22

The Common Type System 24

The Common Language Specification 26

Interoperability with Unmanaged Code 30

The Microsoft NET Framework introduces many concepts, technologies, and terms My goal in this

chapter is to give you an overview of how the NET Framework is designed, introduce you to some

of the technologies the framework includes, and define many of the terms you’ll be seeing when you

start using it I’ll also take you through the process of building your source code into an application or

a set of redistributable components (files) that contain types (classes, structures, etc.) and then explain

how your application will execute

Compiling Source Code into Managed Modules

OK, so you’ve decided to use the NET Framework as your development platform Great! Your first

step is to determine what type of application or component you intend to build Let’s just assume that

you’ve completed this minor detail; everything is designed, the specifications are written, and you’re

ready to start development

Now you must decide which programming language to use This task is usually difficult because

different languages offer different capabilities For example, in unmanaged C/C++, you have pretty

low-level control of the system You can manage memory exactly the way you want to, create threads

easily if you need to, and so on Microsoft Visual Basic 6.0, on the other hand, allows you to build UI

applications very rapidly and makes it easy for you to control COM objects and databases

The common language runtime (CLR) is just what its name says it is: a runtime that is usable by

different and varied programming languages The core features of the CLR (such as memory

man-agement, assembly loading, security, exception handling, and thread synchronization) are available

to any and all programming languages that target it—period For example, the runtime uses

Trang 30

excep-tions to report errors, so all languages that target the runtime also get errors reported via excepexcep-tions Another example is that the runtime also allows you to create a thread, so any language that targets the runtime can create a thread.

In fact, at runtime, the CLR has no idea which programming language the developer used for the source code This means that you should choose whatever programming language allows you to express your intentions most easily You can develop your code in any programming language you desire as long as the compiler you use to compile your code targets the CLR

So, if what I say is true, what is the advantage of using one programming language over another? Well, I think of compilers as syntax checkers and “correct code” analyzers They examine your source code, ensure that whatever you’ve written makes some sense, and then output code that describes your intention Different programming languages allow you to develop using different syntax Don’t underestimate the value of this choice For mathematical or financial applications, expressing your intentions by using APL syntax can save many days of development time when compared to express-ing the same intention by using Perl syntax, for example

Microsoft has created several language compilers that target the runtime: C++/CLI, C# nounced “C sharp”), Visual Basic, F# (pronounced “F sharp”), Iron Python, Iron Ruby, and an Inter-mediate Language (IL) Assembler In addition to Microsoft, several other companies, colleges, and universities have created compilers that produce code to target the CLR I’m aware of compilers for Ada, APL, Caml, COBOL, Eiffel, Forth, Fortran, Haskell, Lexico, LISP, LOGO, Lua, Mercury, ML, Mon-drian, Oberon, Pascal, Perl, PHP, Prolog, RPG, Scheme, Smalltalk, and Tcl/Tk

(pro-Figure 1-1 shows the process of compiling source code files As the figure shows, you can create source code files written in any programming language that supports the CLR Then you use the cor-responding compiler to check the syntax and analyze the source code Regardless of which compiler

you use, the result is a managed module A managed module is a standard 32-bit Windows portable

executable (PE32) file or a standard 64-bit Windows portable executable (PE32+) file that requires the CLR to execute By the way, managed assemblies always take advantage of Data Execution Prevention (DEP) and Address Space Layout Randomization (ASLR) in Windows; these two features improve the security of your whole system

C#

source code

file(s)

Basicsource codefile(s)

IL source codefile(s)

Managed module(IL and metadata)

FIGURE 1-1 Compiling source code into managed modules

Trang 31

Table 1-1 describes the parts of a managed module.

TABLE 1-1 Parts of a Managed Module

PE32 or PE32+ header The standard Windows PE file header, which is similar to the Common Object File Format

(COFF) header If the header uses the PE32 format, the file can run on a 32-bit or 64-bit version of Windows If the header uses the PE32+ format, the file requires a 64-bit ver- sion of Windows to run This header also indicates the type of file: GUI, CUI, or DLL, and contains a time stamp indicating when the file was built For modules that contain only IL code, the bulk of the information in the PE32(+) header is ignored For modules that con- tain native CPU code, this header contains information about the native CPU code CLR header Contains the information (interpreted by the CLR and utilities) that makes this a man-

aged module The header includes the version of the CLR required, some flags, the

MethodDef metadata token of the managed module’s entry point method (Main

method), and the location/size of the module’s metadata, resources, strong name, some flags, and other less interesting stuff.

Metadata Every managed module contains metadata tables There are two main types of tables:

tables that describe the types and members defined in your source code and tables that describe the types and members referenced by your source code.

IL code Code the compiler produced as it compiled the source code At run time, the CLR

com-piles the IL into native CPU instructions.

Native code compilers produce code targeted to a specific CPU architecture, such as x86, x64, or ARM All CLR-compliant compilers produce IL code instead (I’ll go into more detail about IL code

later in this chapter.) IL code is sometimes referred to as managed code because the CLR manages its

execution

In addition to emitting IL, every compiler targeting the CLR is required to emit full metadata into

every managed module In brief, metadata is a set of data tables that describe what is defined in the module, such as types and their members In addition, metadata also has tables indicating what the managed module references, such as imported types and their members Metadata is a superset of older technologies such as COM’s Type Libraries and Interface Definition Language (IDL) files The important thing to note is that CLR metadata is far more complete And, unlike Type Libraries and IDL, metadata is always associated with the file that contains the IL code In fact, the metadata is always embedded in the same EXE/DLL as the code, making it impossible to separate the two Because the compiler produces the metadata and the code at the same time and binds them into the resulting managed module, the metadata and the IL code it describes are never out of sync with one another.Metadata has many uses Here are some of them:

Trang 32

■ The CLR’s code verification process uses metadata to ensure that your code performs only

“type-safe” operations (I’ll discuss verification shortly.)

In Chapter 2, “Building, Packaging, Deploying, and Administering Applications and Types,” I’ll scribe metadata in much more detail

de-Microsoft’s C#, Visual Basic, F#, and the IL Assembler always produce modules that contain aged code (IL) and managed data (garbage-collected data types) End users must have the CLR (presently shipping as part of the NET Framework) installed on their machine in order to execute any modules that contain managed code and/or managed data in the same way that they must have the Microsoft Foundation Class (MFC) library or Visual Basic DLLs installed to run MFC or Visual Basic 6.0 applications

man-By default, Microsoft’s C++ compiler builds EXE/DLL modules that contain unmanaged (native) code and manipulate unmanaged data (native memory) at run time These modules don’t require the CLR to execute However, by specifying the /CLR command-line switch, the C++ compiler produces modules that contain managed code, and of course, the CLR must then be installed to execute this code Of all of the Microsoft compilers mentioned, C++ is unique in that it is the only compiler that allows the developer to write both managed and unmanaged code and have it emitted into a single module It is also the only Microsoft compiler that allows developers to define both managed and unmanaged data types in their source code The flexibility provided by Microsoft’s C++ compiler is unparalleled by other compilers because it allows developers to use their existing native C/C++ code from managed code and to start integrating the use of managed types as they see fit

Combining Managed Modules into Assemblies

The CLR doesn’t actually work with modules, it works with assemblies An assembly is an abstract

concept that can be difficult to grasp initially First, an assembly is a logical grouping of one or more modules or resource files Second, an assembly is the smallest unit of reuse, security, and versioning Depending on the choices you make with your compilers or tools, you can produce a single-file or a

multifile assembly In the CLR world, an assembly is what we would call a component.

In Chapter 2, I’ll go over assemblies in great detail, so I don’t want to spend a lot of time on them here All I want to do now is make you aware that there is this extra conceptual notion that offers a way to treat a group of files as a single entity

Figure 1-2 should help explain what assemblies are about In this figure, some managed modules and resource (or data) files are being processed by a tool This tool produces a single PE32(+) file that represents the logical grouping of files What happens is that this PE32(+) file contains a block of data

Trang 33

called the manifest The manifest is simply another set of metadata tables These tables describe the

files that make up the assembly, the publicly exported types implemented by the files in the assembly, and the resource or data files that are associated with the assembly

Tool combining multiplemanaged modules andresource files into

an assemblyC# compiler(CSC.exe),Visual Basic compiler(VBC.exe),Assembly Linker(AL.exe)

Assembly(Manifest: describes theset of files in the assembly)

Managed module(IL and metadata)Managed module(IL and metadata)Resource file(.jpeg, gif, html, etc.)Resource file(.jpeg, gif, html, etc.)

(.jpeg, gif, html, etc.)

FIGURE 1-2 Combining managed modules into assemblies

By default, compilers actually do the work of turning the emitted managed module into an bly; that is, the C# compiler emits a managed module that contains a manifest The manifest indicates that the assembly consists of just the one file So, for projects that have just one managed module and no resource (or data) files, the assembly will be the managed module, and you don’t have any ad-ditional steps to perform during your build process If you want to group a set of files into an assem-bly, you’ll have to be aware of more tools (such as the assembly linker, AL.exe) and their command-line options I’ll explain these tools and options in Chapter 2

assem-An assembly allows you to decouple the logical and physical notions of a reusable, securable, versionable component How you partition your code and resources into different files is completely

up to you For example, you could put rarely used types or resources in separate files that are part of

an assembly The separate files could be downloaded on demand from the web as they are needed

at run time If the files are never needed, they’re never downloaded, saving disk space and reducing installation time Assemblies allow you to break up the deployment of the files while still treating all of the files as a single collection

An assembly’s modules also include information about referenced assemblies (including their

version numbers) This information makes an assembly self-describing In other words, the CLR can

determine the assembly’s immediate dependencies in order for code in the assembly to execute

No additional information is required in the registry or in Active Directory Domain Services (AD DS) Because no additional information is needed, deploying assemblies is much easier than deploying unmanaged components

Trang 34

Loading the Common Language Runtime

Each assembly you build can be either an executable application or a DLL containing a set of types for use by an executable application Of course, the CLR is responsible for managing the execution

of code contained within these assemblies This means that the NET Framework must be installed

on the host machine Microsoft has created a redistribution package that you can freely ship to install the NET Framework on your customers’ machines Some versions of Windows ship with the NET Framework already installed

You can tell if the NET Framework has been installed by looking for the MSCorEE.dll file in the

%SystemRoot%\System32 directory The existence of this file tells you that the NET Framework is installed However, several versions of the NET Framework can be installed on a single machine simultaneously If you want to determine exactly which versions of the NET Framework are installed, examine the subdirectories under the following directories

In addition, Windows Store applications or class libraries will run on Windows RT machines (which use

an ARM CPU) In other words, the one file will run on any machine that has the corresponding version

of the NET Framework installed on it

On extremely rare occasions, developers want to write code that works only on a specific version

of Windows Developers might do this when using unsafe code or when interoperating with aged code that is targeted to a specific CPU architecture To aid these developers, the C# compiler offers a /platform command-line switch This switch allows you to specify whether the resulting assembly can run on x86 machines running 32-bit Windows versions only, x64 machines running 64-bit Windows only, or ARM machines running 32-bit Windows RT only If you don’t specify a platform, the default is anycpu, which indicates that the resulting assembly can run on any version of Windows Users of Visual Studio can set a project’s target platform by displaying the project’s property pages, clicking the Build tab, and then selecting an option in the Platform Target list (see Figure 1-3)

unman-In Figure 1-3, you’ll notice the Prefer 32-Bit check box This check box is only enabled when form Target is set to Any CPU and if the project type produces an executable If you select the Prefer 32-Bit check box, then Visual Studio spawns the C# compiler specifying the /platform: anycpu­32bitpreferred compiler switch This option indicates that the executable should run as a 32-bit

Trang 35

Plat-executable even when running on a 64-bit machine If your application doesn’t require the additional memory afforded to a 64-bit process, then this is typically a good way to go because Visual Studio does not support edit-and-continue of x64 applications In addition, 32-bit applications can interop-erate with 32-bit DLLs and COM components should your application require this

FIGURE 1-3 Setting the platform target by using Visual Studio

Depending on the platform switch, the C# compiler will emit an assembly that contains either a PE32 or PE32+ header, and the compiler will also emit the desired CPU architecture (or agnostic) into the header as well Microsoft ships two SDK command-line utilities, DumpBin.exe and CorFlags.exe, that you can use to examine the header information emitted in a managed module by the compiler.When running an executable file, Windows examines this EXE file’s header to determine whether the application requires a 32-bit or 64-bit address space A file with a PE32 header can run with a 32-bit or 64-bit address space, and a file with a PE32+ header requires a 64-bit address space Windows also checks the CPU architecture information embedded inside the header to ensure that it matches the CPU type in the computer Lastly, 64-bit versions of Windows offer a technology that allows 32-bit

Windows applications to run This technology is called WoW64 (for Windows on Windows 64)

Table 1-2 shows two things First, it shows what kind of managed module you get when you specify various /platform command-line switches to the C# compiler Second, it shows how that application will run on various versions of Windows

Trang 36

TABLE 1-2 Effects of /platform on Resulting Module and at Run Time

/platform Switch Resulting Managed

anycpu

(the default) PE32/agnostic Runs as a 32-bit application Runs as a 64-bit application Runs as a 32-bit application anycpu32bitpreferred PE32/agnostic Runs as a 32-bit

application Runs as a 32-bit application Runs as a 32-bit application

application Runs as a WoW64 application Doesn’t run

application

After Windows has examined the EXE file’s header to determine whether to create a 32-bit or bit process, Windows loads the x86, x64, or ARM version of MSCorEE.dll into the process’s address space On an x86 or ARM version of Windows, the 32-bit version of MSCorEE.dll can be found in the

64-%SystemRoot%\System32 directory On an x64 version of Windows, the x86 version of MSCorEE.dll can be found in the %SystemRoot%\SysWow64 directory, whereas the 64-bit version can be found

in the %SystemRoot%\System32 directory (for backward compatibility reasons) Then, the process’s primary thread calls a method defined inside MSCorEE.dll This method initializes the CLR, loads the EXE assembly, and then calls its entry point method (Main) At this point, the managed application is

up and running.1

Note Assemblies built by using version 1.0 or 1.1 of Microsoft’s C# compiler contain a

PE32 header and are CPU-architecture agnostic However, at load time, the CLR considers these assemblies to be x86 only For executable files, this improves the likelihood of the application actually working on a 64-bit system because the executable file will load in WoW64, giving the process an environment very similar to what it would have on a 32-bit x86 version of Windows

If an unmanaged application calls the Win32 LoadLibrary function to load a managed assembly, Windows knows to load and initialize the CLR (if not already loaded) in order to process the code contained within the assembly Of course, in this scenario, the process is already up and running, and this may limit the usability of the assembly For example, a managed assembly compiled with the /platform:x86 switch will not be able to load into a 64-bit process at all, whereas an execut-able file compiled with this same switch would have loaded in WoW64 on a computer running a 64-bit version of Windows

1 Your code can query Environment ’s Is64BitOperatingSystem property to determine if it is running on a 64-bit version of Windows Your code can also query Environment ’s Is64BitProcess property to determine if it is running in

a 64-bit address space.

Trang 37

Executing Your Assembly’s Code

As mentioned earlier, managed assemblies contain both metadata and IL IL is a CPU-independent machine language created by Microsoft after consultation with several external commercial and academic language/compiler writers IL is a much higher-level language than most CPU machine languages IL can access and manipulate object types and has instructions to create and initialize ob-jects, call virtual methods on objects, and manipulate array elements directly It even has instructions

to throw and catch exceptions for error handling You can think of IL as an object-oriented machine language

Usually, developers will program in a high-level language, such as C#, Visual Basic, or F# The pilers for these high-level languages produce IL However, as any other machine language, IL can be written in assembly language, and Microsoft does provide an IL Assembler, ILAsm.exe Microsoft also provides an IL Disassembler, ILDasm.exe

com-Keep in mind that any high-level language will most likely expose only a subset of the facilities offered by the CLR However, the IL assembly language allows a developer to access all of the CLR’s facilities So, should your programming language of choice hide a facility the CLR offers that you re-ally want to take advantage of, you can choose to write that portion of your code in IL assembly or perhaps another programming language that exposes the CLR feature you seek

The only way for you to know what facilities the CLR offers is to read documentation specific to the CLR itself In this book, I try to concentrate on CLR features and how they are exposed or not exposed

by the C# language I suspect that most other books and articles will present the CLR via a language perspective, and that most developers will come to believe that the CLR offers only what the develop-er’s chosen language exposes As long as your language allows you to accomplish what you’re trying

to get done, this blurred perspective isn’t a bad thing

Important I think this ability to switch programming languages easily with rich

integra-tion between languages is an awesome feature of the CLR Unfortunately, I also believe that developers will often overlook this feature Programming languages such as C# and Visual Basic are excellent languages for performing I/O operations APL is a great language for performing advanced engineering or financial calculations Through the CLR, you can write the I/O portions of your application in C# and then write the engineering calculations part in APL The CLR offers a level of integration between these languages that is unprec-edented and really makes mixed-language programming worthy of consideration for many development projects

To execute a method, its IL must first be converted to native CPU instructions This is the job of the CLR’s JIT (just-in-time) compiler

Figure 1-4 shows what happens the first time a method is called

Just before the Main method executes, the CLR detects all of the types that are referenced by

Main’s code This causes the CLR to allocate an internal data structure that is used to manage access

Trang 38

to the referenced types In Figure 1-4, the Main method refers to a single type, Console, causing the CLR to allocate a single internal structure This internal data structure contains an entry for each method defined by the Console type Each entry holds the address where the method’s implemen-tation can be found When initializing this structure, the CLR sets each entry to an internal, undocu-mented function contained inside the CLR itself I call this function JITCompiler.

When Main makes its first call to WriteLine, the JITCompiler function is called The JIT­Compiler function is responsible for compiling a method’s IL code into native CPU instructions Because the IL is being compiled “just in time,” this component of the CLR is frequently referred

to as a JITter or a JIT compiler.

Note If the application is running on an x86 version of Windows or in WoW64, the JIT

com-piler produces x86 instructions If your application is running as a 64-bit application on an x64 version of Windows, the JIT compiler produces x64 instructions If the application is run-ning on an ARM version of Windows, the JIT compiler produces ARM instructions

static void Main() {

1 In the assembly that implements the type (Console), look up the method (WriteLine) being called in the metadata

2 From the metadata, get the IL for this method

3 Allocate a block of memory

4 Compile the IL into native CPU instructions;

the native code is saved in the memory allocated in step 3

5 Modify the method’s entry in the Type’s table so that it now points to the memory block allocated

Trang 39

When called, the JITCompiler function knows what method is being called and what type fines this method The JITCompiler function then searches the defining assembly’s metadata for the called method’s IL JITCompiler next verifies and compiles the IL code into native CPU instructions The native CPU instructions are saved in a dynamically allocated block of memory Then, JITCom­piler goes back to the entry for the called method in the type’s internal data structure created by the CLR and replaces the reference that called it in the first place with the address of the block of memory containing the native CPU instructions it just compiled Finally, the JITCompiler function jumps to the code in the memory block This code is the implementation of the WriteLine method (the version that takes a String parameter) When this code returns, it returns to the code in Main, which continues execution as normal.

de-Main now calls WriteLine a second time This time, the code for WriteLine has already been verified and compiled So the call goes directly to the block of memory, skipping the JITCompiler

function entirely After the WriteLine method executes, it returns to Main Figure 1-5 shows what the process looks like when WriteLine is called the second time

Console

JITCompiler

Native CPUinstructions

static void Main() {

2 From the metadata, get the IL for this method

3 Allocate a block of memory

4 Compile the IL into native CPU instructions;

the native code is saved in the memory allocated in step 3

5 Modify the method’s entry in the Type’s table so that it now points to the memory block allocated

in step 3

6 Jump to the native code contained inside the memory block

bly that implements t

alled in thethe metadata, get the IL for this meate a block of mem

pile the IL into native CPU instructionative code is saved in the memoryated in

fy the method’s entry in the Type’s tnow points to the memory block

e native code contained ink

Native

FIGURE 1-5 Calling a method for the second time

Trang 40

A performance hit is incurred only the first time a method is called All subsequent calls to the method execute at the full speed of the native code because verification and compilation to native code don’t need to be performed again.

The JIT compiler stores the native CPU instructions in dynamic memory This means that the piled code is discarded when the application terminates So if you run the application again in the future or if you run two instances of the application simultaneously (in two different operating system processes), the JIT compiler will have to compile the IL to native instructions again Depending on the application, this can increase memory consumption significantly compared to a native application whose read-only code pages can be shared by all instances of the running application

com-For most applications, the performance hit incurred by JIT compiling isn’t significant Most tions tend to call the same methods over and over again These methods will take the performance hit only once while the application executes It’s also likely that more time is spent inside the method than calling the method

applica-You should also be aware that the CLR’s JIT compiler optimizes the native code just as the back end

of an unmanaged C++ compiler does Again, it may take more time to produce the optimized code, but the code will execute with much better performance than if it hadn’t been optimized

There are two C# compiler switches that impact code optimization: /optimize and /debug The following table shows the impact these switches have on the quality of the IL code generated by the C# compiler and the quality of the native code generated by the JIT compiler

Compiler Switch Settings C# IL Code Quality JIT Native Code Quality

/optimize­ /debug­

/optimize­ /debug(+/full/pdbonly) Unoptimized Unoptimized

/optimize+ /debug(­/+/full/pdbonly) Optimized Optimized

With /optimize­, the unoptimized IL code produced by the C# compiler contains many operation (NOP) instructions and also branches that jump to the next line of code These instructions are emitted to enable the edit-and-continue feature of Visual Studio while debugging and the extra instructions also make code easier to debug by allowing breakpoints to be set on control flow instruc-tions such as for, while, do, if, else, try, catch, and finally statement blocks When produc-ing optimized IL code, the C# compiler will remove these extraneous NOP and branch instructions, making the code harder to single-step through in a debugger because control flow will be optimized Also, some function evaluations may not work when performed inside the debugger However, the

no-IL code is smaller, making the resulting EXE/DLL file smaller, and the no-IL tends to be easier to read for those of you (like me) who enjoy examining the IL to understand what the compiler is producing

Ngày đăng: 29/03/2014, 02:20

Xem thêm

TỪ KHÓA LIÊN QUAN

w