Managed Locking

Fast and efficient, and covers most of your needs Like strings, arrays, and delegates, the (System.Threading) Monitor class is a special class with deep roots in the CLR. You can lock any reference type with Delphi code like Monitor.Enter(PrivateReference) try Monitor.Exit(PrivateReference) end or the equivalent C lock (PrivateReference) *locked code* 9 because the header of every object on the heap contains a synch block index in addition to a method table pointer. (As per previous chapters,...

Note The CIL stack is an abstraction Stack underflow errors eg calling add on an empty stack cause a

All methods terminate by calling the ret instruction. (The ret instruction may occur in more than one place within a routine.) A Delphi procedure returns nothing (like a C void method) and should have no values on the stack when it calls ret. A Delphi function (or a C method with a nonvoid return type) should have exactly one value on the stack of the right type whenever it calls ret. You can imagine the ret instruction popping the result from the bottom of the called method's stack (if the...

Covariance and Contravariance

Looser rules for prototype matching in 2.0 Consider the following extract from the Chapter8 NoCovariance8 project public static Derived BaseFn(Base B) return new Derived() class Derived Base delegate Base BaseFunction(Base B) 8. Both Chapter8 NoCovariance and Chapter8 NoContravariance are C 1.0 projects, built in VS 2003. Chapter8 Covariance and Chapter8 Contravariance are C 2.0 projects, built in VS 2005. In 1.x, you can't say BaseFunction F new BaseFunction(Base.BaseFn). A BaseFunction...

The Format Method

Much like the SysUtils Format function, but with a different pattern language The String .Format methods follow some of the same models as the String .Concat methods. Accepting object parameters instead of strings keeps calls to ToString() out of application code, and makes for Simpler code. String.Format accepts object parameters, calls ToString on each, and interpolates the results into a pattern string. This in turn becomes the Format model of passing parameters on to String. Format and...

Strings and Characters

Different quotes for strings and characters Where Delphi uses single quotes for both strings and characters, so that a single element string looks just the same as a single character, C uses single quotes for characters and double quotes for strings. Both string and character literals use the same four slightly different escape mechanisms for characters that you can't see on the screen and for characters that may not be on your keyboard. The first (symbolic) escape mechanism (see Table 5-4)...

Allocating Local Arrays

An unsafe block can use the stackalloc keyword to create a local array, on the stack. The syntax is a bit like creating a new array, except that a stackalloc array can't have an initializer. That is, you can say int* buffer stackalloc int 32 or char* characters stackalloc char Count , but you cannot say int* table stackalloc int 2 1, 2 . Also, you can only use stackalloc to allocate types that you can have pointers to you cannot stackalloc a struct S string s because it contains a string. Note...

Asynchronous Execution

Delegates can be called asynchronously When you call a delegate as if it were a method of the current class e.g., double Result Fn (46D) or Callback(PercentComplete) you are making a synchronous call. The compiler turns what looks like a method call into a call to the delegate instance's CLR-generated Invoke method, which takes the same parameters as the delegate. The Invoke method executes each method on the delegate's invocation list in the current thread, and control doesn't return to the...

Foreground and Background Threads

Foreground threads keep a process alive .NET threads are divided into foreground and background threads. This has nothing to do with thread scheduling while a workstation OS may give higher priority to the application with the UI focus than it gives to other applications, foreground threads do not execute before background threads. Rather, the difference between foreground and background threads is that a process will stay alive as long as it contains at least one active running foreground...

Cross Language Programming

Or An example of why I don't use Delphi for .NET You already know cross-language programming is possible, because both Delphi and VB can use and extend the FCL, which is written in C . However, there's nothing quite like having all the code in your hands, so I'll conclude this chapter with an example of a trivial Delphi application creating and inspecting an object with layers written in three different languages, the Chapter2 CrossLanguage BDS 2006 project group. The first layer, or base...

The Main Method

All C executables (as opposed to libraries) must have at least one object (either a class or a struct) with a static Main method. The Main method, like a Delphi program file's begin end. block, is the program entry point. The Main method must return either int the application's result code or void. That is, either static void Main() or static int Main(). Whether void or int, Main can have a string args parameter, which allows easy access to any command-line parameters. You do not have to...

Printing

.NET printing is based on the PrintDocument component. (You can place a PrintDocument on a form as a nonvisual component, or you can create one as necessary.) A PrintDocument has a PrintPage event that allows you to specify page settings draw to a supplied Graphics (much like a Paint event) and specify whether there are any more pages. The PrintDialog component has a Document property that allows the printer setup dialog to set a PrintDocument to the user's choice of printers and settings. The...

Date Formats

How the DateTime type interprets the optional formatting component The DateTime object supports standard and custom formatting strings, much like the system numeric types. Standard date formatting strings are single characters unsupported characters generate exceptions, while longer strings are custom date formats. As with the numeric types, if you don't specify a formatting component, you get the G format. Table 11-2 is a brief overview of the standard DateTime formats for more details, see...

Delegates

Flexible processing of each element in an enumeration Most foreach loops will use hard-coded logic. However, as always, delegates add flexibility and can save space. For example, sometimes you need to apply the same logic to several different input streams. You can write a series of foreach loops that passes each element of each stream to the same method, or you can make a series of calls to a method that takes an enumeration parameter and a predicate parameter. Each method call takes a lot...

Worker Threads

What the system uses to run asynchronous delegates This is why the FCL supplies a ThreadPool that can run a delegate in a background thread (creating a new thread, if necessary) and then cache the thread for later reuse. For example, the preceding simple thread could be recoded, using the ThreadPool, as using (StreamReader Reader new Source Reader.ReadToEnd() A WaitCallback delegate is a delegate to a method that takes a single object parameter and returns nothing delegate void WaitCallback...

Note In unsafe code you can also add and subtract bit integers to and from pointers and you can do a

By default, arithmetic operations do not do overflow checking, and simply return the low order bits of their result. There are overloads, like add.ovf and mul.ovf, that will check the results and raise an exception on any overflow. You have perhaps noticed that the load and store instructions are all very explicitly typed, while we use the same add instruction for adding 1-byte integers as for adding 8-byte floats. Is it fair to say that CIL operators are untyped Is there any possible loss of...

Assignment Operators

Aside from the obvious fact that Delphi uses for assignment where C uses for assignment, there are two key differences between assignment in Delphi and C . First, in C , assignment is an operator like any other, and you can write code like TopLeft.Left LeftSide.Left BottomRight.Left ClipRect.Left + Inset that sets three properties to the same value in a single statement. This is very simple and clean the single statement communicates intent better than the equivalent code split into three or...

Using NUnit

Tip You can download NUnit from http www.nunit.org. You need to use NUnit version 2.2.3 (or later) to test 2.0 assemblies. Version 2.2.6 works with the 2.0 run time as is with earlier versions, you may need to uncomment the < startup> section of the nunit-gui.exe.config file to force the test harness to use the 2.0 run time. An NUnit test assembly is an assembly containing NUnit tests, which are individual methods of TestFixture classes. The NUnit test harness loads the test assembly in an...

Numeric Expressions

In Delphi, the type of a numerical expression like A + B is the type of the wider of A or B the narrower of the two operands will be implicitly widened. Similarly, when you assign a wide result to a narrow variable (e.g., IntVar ThisInt64 + ThatInt64), the result will be automatically narrowed, and optionally checked for overflow. C also automatically widens operands, but does not do any implicit narrowing of expression results on assignment. You can say ThisInt ThatInt + ThisByte but not...

Multicast Events

Delphi for .NET has full support for both old-style single-cast events and .NET-style multicast events. To write a traditional Delphi event, you first declare a delegate type using the procedure of object syntax, then declare an event property that references a delegate field in the read and write specifiers. TLevelChangedEvent procedure (Sender TObject NewLevel integer) of object TMyComponent class strict private FOnLevelChanged TLevelChangedEvent public property OnLevelChanged...

Enums

In Delphi, each element of an enumerated type is an element of the namespace. That is, type Colors (Red, Green, Blue) defines four names Colors, Red, Green, and Blue. This is very convenient in small programs, but in larger programs most people end up using some sort of qualified name like type Colors (clrRed, clrGreen, clrBlue) or even type Colors (colorRed, colorGreen, colorBlue). Qualifying enum names like this reduces the potential for conflicts. Adapting this reasoning to the general .NET...

Tip Each field of the OpCodes type corresponds to an instruction overload So the page for say OpCode

There are a few things you might find puzzling about ILDASM, so I'll walk you through the unassembly of a couple of methods. Those of you wanting more background on more instructions will find some of that in these two walkthroughs. The sample code in this section is in C . I do this for several reasons. First, the C code is considerably shorter than the equivalent Delphi code, and each page of each copy of this book has an economic and environmental cost. Beyond printing costs, I think you'll...

File System Information

Both low-level, filename-oriented classes and higher-level objects The System.IO namespace provides two types of access to files. The Path, Directory, and File classes are static classes (in 1.1, they're sealed, abstract classes) with static methods. They provide logical grouping, but are only minimally object oriented. The DirectoryInfo and FileInfo classes are regular classes each instance represents a file or directory, and there are properties to read and write timestamps and the like. The...

Coordinate Transforms

All Graphics operations are subject to transformation by the Matrix Transform property. This is a 3-by-3 floating point matrix that, as per basic linear algebra, efficiently encodes any rotations, translations, and scaling you might want to apply to a set of coordinates. For the benefit of those of us whose linear algebra is long ago and far away, the Graphics class provides methods like RotateTransform, TranslateTransform, and ScaleTransform that make it easy to do rotations and to apply...

Floating Point Semantics

Native Delphi signals invalid floating point operations by raising exceptions such as EZeroDivide and EOverflow. By default, these semantics are preserved in Delphi for .NET. However, while the native code floating point exceptions come straight from the processor hardware and so are quite efficient, getting floating point exceptions under .NET means that the compiler must explicitly emit the ckfinite CIL instruction. For example, a division statement generates CIL code like...

Inlining and Properties

.NET may be able to optimize property access One place that inlining can make a big difference is with object properties. While .NET includes the notion of object properties, just as Delphi always has, one of the differences between .NET and Delphi is that you can only read or write .NET properties via methods, not via direct field access as in Delphi. That is, in Delphi one might write property Bar integer read fBar write fBar The native Delphi code uses the field directly as a property...

Lowlevel GUI Access

When WinForms doesn't wrap the functionality you need In WinForms as in Delphi, controls are object-oriented facades for the flat functions that create and manipulate the various specialized windows that Windows can create panels, buttons, edit boxes, tree views, and the like. These specialized windows send messages to the form, which the window function handles and dispatches to our event handlers. Our facades control their specialized windows by calling the right flat functions and or sending...

The switch Statement

Awkward syntax, but can switch on strings A switch statement consists of the switch keyword, followed by an integer or string expression in parentheses, followed by a series of case statements within a pair of curly braces. Each case statement consists of a case clause, followed by a list of statements. Each statement list must end in a jump statement (or an infinite loop) control may not pass out of the statement list. A case clause is one or more regular or default case clauses. A regular...

Interprocess Communication

Uses serialization to make remote calls Historically, communication between processes and between machines has been a complex affair. However, as in so many other areas, the designers of .NET took all the best ideas, and the result is a subsystem that makes communication between .NET processes almost absurdly easy while still being quite configurable. Using the defaults, you can get .NET remoting working with just a few lines of code, yet you can easily change the communications channel, add...

New Array Syntax

While native Delphi supports both static and dynamic arrays, Delphi for .NET now also supports multidimensional, rectangular dynamic arrays. These differ from jagged array of arrays in that there is only a single, continuous block of memory allocated for the items in it, and the size of all dimensions can be set dynamically at run time. This is mostly a performance and memory usage optimization, but it is also required to be able to interface with external code that uses multidimensional...

Application Domains

Isolated, like a process, but cheaper I've mentioned a few times that in general jitted code is never unloaded data comes and goes, but code sticks around forever. I've also mentioned that while this is mostly true, it is an oversimplification. This subsection covers some of the details. All code runs in an application domain, or AppDomain. The CLR creates a couple of hidden app domains for its own use, and then loads application code into the default AppDomain. Any code loaded into the default...

The foreach Statement

A concept that may be familiar from scripting languages The foreach loop is both like and unlike the for loop. The for loop is a low-level, almost macrolike construct that can actually implement all three of the other loop types.3 The for loop imposes few restrictions on its three clauses, or on the loop body you can read every other entry, if you need to, and you can change the loop control variable. By contrast, in some ways the C foreach loop actually acts more like Delphi's for loop than...

Component Scope

In Delphi, a form's controls are published fields. Since published is public (with RTTI), you can write code that reads and writes EditBox4 from outside the form. (Your coworkers may shun you both for accessing another form's controls directly and for not giving the control a more distinctive name but the compiler won't stop you.) In WinForms, control fields default to private, but can be set to protected or internal or whatever by changing their Modifiers property. You should be very...

The Free Pattern

The Borland .Delphi .System unit declares the TObjectHelper class helper that injects methods like Free and ClassName into all classes (including FCL classes). The Free method is special and implements deterministic disposing of unmanaged resources by calling IDispose .Disposable (if it is implemented by the class). if (Self < > nil) and (Self is IDisposable) then begin (Self as IDisposable).Dispose end end To complete the cycle, the compiler effectively transforms an overridden Destroy...

Constructors

One of the first things one needs to do with a Type value is to create instances of the type. For example, a system options dialog, where each subsystem can choose to register (at startup time) the typeof() of their UserControl descendants along with the appropriate catalog data. (A UserControl is much like a Delphi TFrame see Chapter 15.) When if the dialog is actually created, the dialog creates each page's UserControl the first time it comes to the front.10 9. One thing to note when you...

Multiunit Namespaces

With the trinity of a logical unit concept, physical unit source .pas files, and compiled .dcu files, Delphi has always had a very efficient and useful module concept. To address the hierarchal namespace support required in .NET while still being backwards compatible, Delphi 8 introduced the concept of dotted unit names, such as Borland.Vcl.SysUtils and Borland.Vcl.Classes these unit names were mapped directly to .NET namespaces. This was a step in the right direction, but Delphi 2005 extended...

Table Cross Reference

Set Operators and Their Bitmapped Equivalents 48 Table 3-1. Results from the Chapter3 MakingTrouble Project 65 Table 5-1. System Table 5-2. C Operators That Are Different Than Delphi Operators 112 Table 5-3. Operator Precedence Table 5-4. Symbolic Character Table 5-5. Hexadecimal Character Table 7-1. Constructor Table 8-1. Interface and Delegate Tradeoffs 188 Table 10-1. Obsolete Table 10-2. Delphi Language Features Table 10-3. C Language Features Table 11-1. Standard Numeric Table...

Threadlocal Storage

Ways for each thread to have its own variables One of the reasons to use a thread, as opposed to a process, is that it has access to its parent process's address space. It can 'see' any public static variables and if the thread delegate points to an instance method the thread delegate can access any instance members in a perfectly ordinary way. An object created in one thread can be accessed by any other thread that can 'see' the object. Still, there are times when a thread needs its own copy...

Unsafe Code

Delphi for .NET now supports unsafe code. As in C (Appendix 0), you have to first enable unsafe code with the ( UNSAFECODE ON compiler directive, and then you have to mark the method with the unsafe directive. Unlike C , you cannot have unsafe classes with pointer fields, and you cannot have unsafe blocks within safe methods. function Foo(const A array of char) integer unsafe var Fixed GCHandle.Alloc(A, GCHandleType.Pinned) try P Pointer(Fixed.AddrOfPinnedObject) Result 0 while PA < > 0 do...

Other Ways to

The fixed statement is definitely the simplest way to pin data in a C program, but you may occasionally need to lock memory manually. Manual pinning takes a lot more code than automatic pinning with the fixed statement, because you have to explicitly write a finally block to manually unlock every instance that you manually lock. Most of the manual pinning methods use the value type, IntPtr. On 32-bit platforms, an IntPtr is a struct that's both an int and a pointer you can cast an IntPtr to an...

Obsolete Features

Some things are not possible in managed code Due to the managed and garbage-collected nature of the .NET environment, a number of features specific to native code had to be left out of the Delphi for .NET dialect of the language (see Table 10-1). Most of these are already warned against when you compile with the Win32 compiler, easing the porting process. Including PChar, operator, GetMem, etc. See Unsafe Code earlier. This is a relic from the Turbo Pascal days. Size of records are not fixed in...

Linear Gradient Brushes

There are two types of gradient brushes in the System .Drawing .Drawing2D namespace the LinearGradientBrush and the PathGradientBrush. The next subsection discusses path gradient basics and uses the PathGradientBrush to draw spherical highlights, but for the most part path gradients are complex and specialized and beyond the scope of this book. The LinearGradientBrush, though, is fairly straightforward, and is an easy way to give your applications an attractive XP look. Most of the time, you'll...

Proxies

Getting a remoting proxy with the AppDomain instance method CreateInstanceAndUnwrap is the most flexible way to make calls between application domains. The CreateInstance family of methods all load the assembly you specify into the instance AppDomain do a GetType on that assembly to find a type that you specify by name create an instance of that type and return a proxy for that new instance. Thus, in the AppDomainDemo's Plugin example, Gateway Proxy (Gateway)ProxyDomain.Domain. Shim.Gateway)...

Redefining the Operators

Long-time Delphi programmers have looked at the operator overloading features of other languages (such as C++) with both fear and envy. Operator overloading lets application code use infix operators with user-defined types. When used properly, this is a powerful and elegant technique that can make code smaller and clearer however, when used improperly, operator overloading can make your code much harder to read and maintain. Note This subsection only outlines Delphi operator overloading syntax....

NET Threads

Delphi's TThread class is a little strange you use it by defining a class that inherits from TThread and overrides the Execute method. When you create an instance of your thread class, it runs its Execute method in a new thread. This is bad because it tends to violate encapsulation. Typically we want our threads to act with and on the program's existing objects our forms and our data models. Putting the thread code into a separate thread object means that that thread object has to know an awful...

Configuration Files

An application configuration file is an XML file in the application directory, with the same name as the application, with .config appended. For example, the configuration file for MyApp.exe would be MyApp.exe.config. The file should have a standard < xml version 1.0 encoding utf-8 > XML header and a configuration root element. Tip In Visual Studio, using the Add New Item dialog to add an Application configuration file adds an App .config source file with a minimal XML structure. When you...

Arrays

Syntax is quite different than Delphi's Arrays are declared as a type name followed by square brackets, as in int or object . C arrays are always indexed by numbers, starting at 0. Multidimensional arrays are declared by adding commas between the square brackets, as in int , for a two-dimensional array of integers or int ,, for a three-dimensional array of integers. Unlike Delphi, there is no static sizing in array declarations, and there is no way to declare a particular sort of array as a...

Tip Using a Draw Image overload that allows you to specify the image size like the overloads that tak

More complex DrawImage overloads allow you to apply an ImageAttributes object to the Bitmap draw. You can do an awful lot of interesting things with an ImageAttributes. The SetOutputChannel method lets you do color separations draw an RGB color image to a set of four grayscale images that represent the Cyan Magenta Yellow Black (CMYK) level for each pixel. The SetRemapTable method lets you register a list of colors to draw as, say, Color. Transparent, or you can use the SetColorKey method to...

Aborting and Interrupting Threads

It's safer to Interrupt than to Abort In unmanaged code, aborting a thread is a very dangerous thing to do. If you simply stop a thread when the user hits Cancel, you don't really know what the thread was doing. Open files or graphics handles will never be closed, which is a resource leak that could destabilize the system. Worse, any resource the thread had locked will never be released any thread waiting for that resource (and any thread that subsequently tries to lock that resource) would...

File IO

Reading and writing text and binary files The File class has static methods like Exists and Delete that do exactly what you'd expect. It also has static methods like Open that return a new FileStream object a FileStream object represents an open file. Similarly, the FileInfo class has an Exists property and a Delete method as well as various Open overloads that all return a new FileStream. By itself, the FileStream only offers byte-by-byte access to a file. There are blocking and asynchronous...

Pens

Very like Delphi's, but with more features In the FCL as in Delphi, a pen outlines and a brush fills. You use a pen to draw lines and curves, rectangles and polygons. The FCL Pen has a Color and a Width property, as well as a DashStyle and an optional DashPattern property. These let you draw solid or patterned lines, and act almost exactly like the Color, Width, and Style properties of the Delphi TPen. Most of the Graphics class Draw methods (that is, all the Draw methods except DrawString,...

Stacks and Queues

The FCL System.Collections namespace includes Stack and Queue classes, which support stacks and queues of objects. These act much like the TStack and TQueue classes in the Borland Contnrs unit, except that the Queue class is substantially more efficient than the TQueue class.10 9. I have read that the 2.0 team chose Dictionary< ,> over Hashtable< ,> because they wanted to be free to use multiple implementations in the future, but that the only current implementation is a Hashtable....

Key Points

.NET has great thread primitives, but threading is still a lot harder than it looks Threads allow a program to do several things 'at once.' A thread shares memory with other threads in its process. Locking critical sections is the key to ensuring that simultaneous access to data structures doesn't result in scrambled data structures or meaningless results. The .NET Thread class is a simple class that runs a delegate in its own thread. The Monitor class and the C lock statement cover most of...

Assemblies

The System .Reflection.Assembly class is important in much the same way as the Type class. Static Assembly methods load assemblies into the current application domain, and return an Assembly instance that describes the loaded assembly. An Assembly instance gives you access to the assembly's types and the assembly's resources. There are also static methods that reveal occasionally invaluable bits of information about the call stack, like GetExecutingAssembly, which returns the Assembly that...

Interfaces

Not reference counted, but otherwise only differ from Delphi in minor details Interfaces are types as are enums, classes, structs, and delegates and can be declared either as members of a namespace Chapter 9 or nested in a class. Interfaces can contain both method and property declarations. Like abstract method declarations, interface declarations have a semicolon instead of a method body. Classes can only inherit from a single base class in both C and Delphi Chapter 7 . However, in native code...

Tip If you are creating a form programmatically remember to add controls to the Controls collection

The WinForms z-order design is a lot simpler than the VCL's multipass design. But the VCL asks a lot less of a form designer than WinForms does. Or something like that because, until recently, if you didn't create your docked controls in just the right order, your options were to either cut and paste controls in the form editor losing event handlers in the process or to edit the InitializeComponent source to change the order that you add controls to the container's Controls collection. In VS...

Note Remember when you set a field of an object instance you always put the instance reference on th

The first formal parameter, the int Value. Again, you have to keep track of which parameter has which number ILDASM misses its chance to annotate this as ldarg. 1 Value. IL_0002 stfld int32 testLibrary.testClass aField The first value on the stack is a reference ldarg .0 set the object's aField field to the second value ldarg.1 . These three instructions implement this.aField Value. The closing . Remember, the ret instruction can occur in more than one place. The comment here is another ILDASM...

String Conversions

Formatting and parsing n umbers and dates As you've already seen, the various overrides and overloads of the Object .ToString method are the FCL equivalent of Delphi's functions like IntToStr and IntToHex. A 'bare' ToString call gives the default format, which is generally the most compact format. Numbers and dates also support a ToString FormatString overload, which allows you to format values as in String.Format. That is, values are responsible for formatting themselves. Similarly, each...

Explicit Event Syntax

The second type of event declaration uses a more complex event syntax, with explicit add and remove methods event DelegateType EventName add add value remove remove value declares an event that even within its own object can only be accessed through the add and remove methods. That is, subscribe with or unsubscribe with - . Typically, this second type of event will be pretty straightforwardly mapped to a private delegate field public event EventType EventName EventType must be a delegate type...

Callback on Completion

Every delegate's Beginlnvoke method has two extra parameters after any Invoke parameters the first is an AsyncCallback delegate and the second is an arbitrary object. If the AsyncCallback delegate is non-null, the asynchronous mechanism will Invoke it synchronously in the same ThreadPool thread11 that runs the delegate see the Chapter8 AsynchTest project once the asynchronously invoked delegate returns. An AsyncCallback delegate takes a single parameter, which is the same IAsyncResult that...

The NET Memory Model

Hides the details of memory synchronization In native code on a single-processor machine, careful use of the various synchronization primitives is all that you need to build reliable multithreaded applications. However, multiprocessor systems can present special challenges, because each processor may have its own cache.12 If ThisThread 12. Hyperthreaded processors share cache, as do some not all multicore machines. has SomeVariable in its cache and then ThatThread changes SomeVariable, you want...

Waiting for Completion

If the asynchronous delegate has any side effects, other threads may want to wait for it to complete before doing anything that depends on those side effects. These threads can use WaitHandle methods Chapter 17 like the IAsyncResult.AsyncWaitHandle.WaitOne instance method or the static WaitHandle methods WaitAll and WaitAny to wait until the IAsyncResult. AsyncWaitHandle event is signaled. While you can call Beginlnvoke in one thread and call Endlnvoke in a different thread, this still allows...

NET Is Not Interpreted

Chapter 1 covered a number of important advantages of managed code No memory corruption from unchecked casts from unchecked array indexing from dangling references, aka tombstoned pointers or from pointer arithmetic. Managed code is easier to write than unmanaged code, because it doesn't need to be cluttered with memory management boilerplate, and because eliminating certain common types of errors means that you get your code working sooner. Managed code is easier to read than unmanaged code,...

Multithreading

Garbage collection suspends secondary threads In any heap system, whether manual or automatic, multithreaded programs have to synchronize access to the free list, in exactly the same way that they have to synchronize access to any other global data structure. For example, in a native code Delphi, when IsMultiThread is True because you set it manually or you created a TThread , the memory management functions use a critical section to assure exclusive access to the free list. Using a critical...

SOAP Bubbles

Finally, you can force an XmlSerializer to generate SOAP-formatted XML by using an XmlTypeMapping. You create an XmlTypeMapping by creating a SoapReflectionlmporter and passing the root Type to the importer's ImportTypeMapping method. You then pass the type mapping to the XmlSerializer instead of the root Type. That is, instead of serializing like using Stream Write new FileStream Filename, FileMode.Create XmlSerializer Serializer new XmlSerializer typeof Data Serializer.Serialize Write, One...

Nullable Types

Arithmetic and logical operations with a none of the above value C 2.0 adds nullable types. A nullable type is a normal value type with a question mark after it. Where a normal bool enum value can be true or false, a bool nullable bool can be true, false, or null. Similarly, an int can hold any int value or null, while a Color can hold Color.Red, Color.Green, Color. Blue, or null. This adds a not-set value to every number, enum, and struct. Note The point of a nullable type is that it adds null...

Events

The .NET event model is based on delegates Once again, all delegates are compiler-generated classes that descend from MulticastDelegate, which descends from Delegate, which descends straight from object. So, delegates are either assigned i.e., a Delegate instance or unassigned null or Nil . Unassigned delegates are 0-length delegates you will never see an assigned delegate with zero handlers when you use the system Delegate methods to manipulate the invocation list. All assigned delegates...

Folding Regions

Visual Studio and, to a lesser extent, BDS does a pretty good job of generating folding regions automatically you can automatically fold methods, classes, blocks, and so on. When you want to combine several methods and fields into a folding region of their own or when you want to divide a long method into multiple folding regions you use the region and endregion directives. Any text between a region directive and the end of the line will appear in gray, in a gray box, when the region is folded....

Collections

The Array class provides a great deal of standard functionality. Arrays are fixed length and strongly typed, but list classes with a Capacity and a Length can support appending, inserting, and deleting. An ArrayList is a list of object references, and so can hold any data types a List lt T gt is a strongly typed list that can only hold T types. Both these lists are indexed by integers the Hashtable andDictionary lt K, V gt can be indexed by any data type. IEnumerable is everywhere in .NETcode...

Regex Match Methods

From binary tests to getting every match There are three different matching methods IsMatch, Match, and Matches. If all you really care about is whether the regex matched or not, the IsMatch method is a convenient shorthand for calling the Match method and examining the Match object it returns. That is, code like ThisRegex.IsMatch ThisText is a bit smaller and easier to read than ThisRegex.Match ThisText . Success. Since all you care about is Success and not all the details of the Match,...

Threads and Synchronization

It's easy to write multithreaded code what's hard is to write reliable multithreaded code. Threading primitives are not hard to understand, and the .NET implementations are particularly good, but it's all too easy to write code that fails randomly and so is hard to debug. The Thread class executes a delegate in a new thread, and the ThreadPool can execute delegates without creating a new thread every time. The Monitor class provides efficient locking and simple signaling, and there are object...

Polling for Completion

It's not always a good idea to block the application's main thread. It's OK in a command-line utility that simply runs to completion with no user intervention, and it's OK in a web server where each incoming request runs in its own thread, but it's generally not OK in a GUI app, where blocking the main thread means that the app is not responding to mouse clicks and key presses. If you initiate a lengthy asynchronous call from the main GUI thread, you might poll the IAsyncResult.IsCompleted...

Subranges

Represented as an enum, which loses some semantics When you declare a subrange like type Subrange 1 10, the Delphi compiler both chooses an integer type that can hold a Subrange value and creates compile-time constants for High Subrange and Low Subrange . This means you can declare variables of the Subrange type, like var Index Subrange, and can write code that knows the variable's range, like for Index Low Index to High Index . It also means that the compiler can detect illegal assignments...

Lists

A familiar design, with some new features Arrays are great, if they never need to change size, or if they only change size very rarely. However, when you need to add items to a collection one by one, and won't know how big your collection is until you're done, continuously resizing an array is an expensive operation. Typically, you would use an array with an auxiliary Count variable the array length is the current Capacity, while the Count is the number of array elements that actually hold real...

Disposing and Not Finalizing

Many classes dispose, few classes finalize You don't need a finalizer just because you use classes that have finalizers. Those classes are already fail-safe, and your class's finalizer couldn't call any methods on those objects, anyhow. However, if you Dispose of or Close those objects in your Dispose method, they won't need to be finalized. That is, many classes support IDisposable without also supporting finalizers.9 In general, if you use a class that implements IDisposable, you should call...

Large Object Heap

It's expensive to relocate large objects The same studies of program behavior that laid the empirical basis for the garbage collector's three-generation design also found that large allocations tend to be long-lived objects IO buffers, application-level caches, and the like. This means that a large object is more likely than a smaller object to need to be relocated. At the same time, relocating a large object is a comparatively expensive operation, both because it runs at memory speed, not CPU...

CLS Rules

While CLS compliance is prima facie a sort of lowest common denominator affair, it's not as bad as it may sound. CLS-compliant code can use inheritance, interfaces, exceptions, and attributes. In fact, it's even OK for a CLS-compliant assembly to include noncompliant features it just has to explicitly label them as noncompliant with the CLSCompliant false attribute. Naturally, if you do expose noncompliant features, like sets or unsigned integers, you should also expose compliant methods that...

Open Types

In 2.0, you can get the typeof of an open type or a closed constructed type just as you can get the typeof a normal closed type such as you can create in 1.x , and the Type class has some new properties and methods to handle open types. The Type. IsGenericType property tells you if a given Type is either an open type or a closed constructed type for example, IsGenericType is false for typeof int but true for both typeof List lt gt and typeof List lt int gt . The related...

Delphi Note Just to be clear Delphi for NET does have metaclasses just as native code Delphis do

Metaclasses are Delphi's class of types. Metaclasses support virtual class methods, but metaclasses are most commonly used for polymorphic object creation. For example, you may have used code like function AnyException Meta MetaException const Msg string Exception begin to write a routine that could log and throw any exception. Other common uses of metaclasses include object streaming and container forms. Delphi's form loading depends on metaclasses, and many applications include custom object...

Modifiers

The syntax category that includes access modifiers I've covered the access modifiers like public and private and so on, but their optional position before a member's type is actually just a special case of the more general group of modifiers. There are other modifiers, like static and virtual, new and override. Modifiers come between any attributes and the member's type Member private static int Field 0 There are rules that govern when a modifier is present, so I will discuss each modifier as...

Search

Find elements that match a target, and elements that satisfy a custom predicate In 1.1, there are only two methods that search an array IndexOf and LastIndexOf. IndexOf searches forward, while LastIndexOf searches backward both search an array for a target object, returning an array index or a failure code. In 2.0, the index-of methods gain typed overloads, plus there is a suite of new methods that apply a predicate to an array in various ways. Both IndexOf and LastIndexOf are static methods...

Compiletime Attributes

Attributes that affect compiler behavior Most attributes are essentially transparent at compile time. They are custom metadata, meant to be read at run time. All that the compiler does with these run-time attributes is syntax check the declarations, and add them to the metadata run-time attributes don't affect the compiler's symbol table the way that types and type members do. There are, however, five special attributes that do have compile-time effects CLSCompliant, DllImport, AttributeUsage,...

Note Delphi only needs virtual constructors because it has strongly typed metaclasses

That does not mean that you cannot do polymorphic object creation. The Chapter2 Polymorphic Delphi project contains the .NET equivalent of the AnyException function function AnyException Meta System.Type const Msg string Exception begin Result Exception Activator.CreateInstance Meta, Msg end WriteLn E is System.ApplicationException The project prints True and then raises an ApplicationException this AnyException function works just as well as its metaclass...

Concatenation Methods

In which we meet some common overload models The String .Concat overloads set a pattern that you'll find repeated throughout this chapter. There are overloads that take one, two, three, or four object parameters, and there is an overload that takes a params object parameter. There are overloads that take two, three, or four string parameters, and there is an overload that takes a params string parameter. All Concat overloads return a single string. Now, as per Chapter 9, the params array...

Wait Handles

More sophisticated locking, at a noticeably higher cost The Monitor class will cover maybe 90 of your synchronization needs. Because using the Monitor class involves neither operating system calls nor finalizers, you should always make the Monitor class your default synchronization solution, only turning to WaitHandle descendants when you need to do cross-process or cross-AppDomain synchronization, or when the Wait Pulse mechanism can't solve your signaling needs. The abstract WaitHandle class...

Iterators

Performance is nearly identical to manual enumerators As you've seen, it's not very hard to implement IEnumerable for simple enumerations. Iterators are clearly much simpler for recursive or other complex enumerations, but should you reserve iterators for complex enumerations that aren't easy to implement as two methods and a property One final thing the Chapter12 Shemitz.Collections C project shows is that iterators perform about as well as manual enumerators. The benchmarks vary a bit from...

Delphi Note In Delphi array is a keyword and you have to call static methods as eg Array Copy or Syst

The static Copy method allows you to copy portions of an array. You can copy either the first N elements from one array to another, or as with the String.Substring method you can copy a given number of elements from a given offset within the source array to a different offset within the target array. Both Copy and CopyTo will raise an exception if the target array is too short, or if the base types are not compatible. While both Copy and CopyTo will copy array elements from one array to...

Colors

As per Chapter 15, every pixel that you draw or fill has a 32-bit ARGB color, where A is eight bits of opacity, or Alpha. Except for Color.Transparent, the system colors like Color.Red or Color. LightSeaGreen are all fully opaque. Their alpha channel is 255, or 100 . Similarly, the standard pens and brushes, the Pens.Black and Brushes.LightBlue that I cover later in this chapter are all fully opaque. When you draw an opaque color to a pixel, the pixel's color is set to the color's RGB...

JIT and CIL

Your code is delivered as CIL Common Intermediate Language , not native machine code. Yet, your code is always compiled to native code before being run. This compilation can happen at install time, but is usually done on a Just In Time basis. Managed code is good for both users and developers, and delivering your code as CIL is key to delivering the benefits of managed code to users intermediate code can be verified before it's run, and running all code through a single...

Wait Callbacks

Reducing the number of blocked threads Many tasks that take significant clock time actually take comparatively little CPU time, because they spend most of their time blocked, waiting for an OS wait handle. They may be waiting for network activity, file IO, a timer, or whatever. As an alternative to creating a thread that spends a lot of time blocked, waiting for one event or another, you can use ThreadPool. RegisterWaitForSingleObject to register an OS wait handle and a WaitOrTimerCallback...

Path Gradient Brushes

Path Gradient

A path gradient runs from the outside of an arbitrary graphics path to an arbitrary center point. This can be useful, especially with simple, smooth curves. For example, when you use FillPie to fill a quarter circle with a path gradient centered on the circle's center, you get a rounded border gradient, as in Figure 16-6 and the Chapter16 CornerGradient C project. Similarly, when you use FillEllipse to fill a circle with a path gradient that's somewhat displaced from the circle's center, you...

XML Reader

Using the XmlReader class is a bit more complicated than using the XmlWriter class, especially in 1.x. Using the XmlWriter is a matter of writing a start element writing any attributes or child elements and then writing an end element. The XmlWriter class takes care of details like indenting, and it keeps track of whether the current element has any child elements or not, so that when you write an end element the XmlWriter knows whether it should just write gt to close an empty element, or...

Other Collection Interfaces

Who offers what, and where it matters There are five collection interfaces worth paying attention to IEnumerable, ICollection, IList, IDictionary, and in 2.0 IEnumerable lt T gt . There are also the open interfaces ICollection lt T gt , IList lt T gt , and IDictionary lt K, V gt , but these are not used quite as heavily as their closed counterparts. This section has covered IEnumerable and IEnumerable lt T gt fairly thoroughly. The two are ubiquitous in FCL code you will always use enumerators,...

Sort

The Sort method is heavily overloaded. All but one of the Sort methods fall into one of two groups the IComparable overloads sort types that know how to compare themselves, in ascending order, and the IComparer overloads take a sorting predicate in the form of an instance of an object that implements the IComparer interface. These two basic models are then multiplied by Subarray overloads that sort only a portion of an array by key item sorting that sorts two arrays based on the values in just...

Tip A lazy create property is a good place to use a weak reference

When you need the data again, you can examine the weak reference's Target and or IsAlive properties. The Target property will either contain a valid reference or Nil null the IsAlive property is true whenever Target is non-Nil. If the Target is Nil, that means the weakly referenced object has been garbage collected and you need to re-create it. If the Target is not Nil, you now have a normal strong reference that you can cast to the appropriate type, and that will keep the data from being...

Fonts and Text

Versatile drawing and immutable fonts While the syntax differs slightly, the FCL Font is much like the Delphi TFont it has a font Name that specifies a typeface, as well as Size, Bold, Italic, Underline, and Strikeout properties. You use a Font to draw a string on a Graphics surface, and you can also use a Font to see how many pixels it would take to draw a string on a Graphics surface. Overall, the biggest surprise is that FCL fonts are immutable all Font properties are readonly. With a Delphi...

Latebound Lists

An ArrayList is like an Array that you can Add to The ArrayList class in the System.Collections namespace is a variable-sized list of object values basically an array with an extra count of the slots actually used. The read-only Count property is the number of items in the list. The Capacity property is the size of the underlying array, the number of items the list can hold before it needs to be resized. The ArrayList class has three constructors the no-parameter constructor gives you a new...

Nested Types

Applying the Thing model to nested types, you might expect Type. GetType to return a nested type's TypeInfo object, and Type.GetTypes to return an array of TypeInfo objects. But nested types are a special case types can exist outside of a type in way that fields and properties can not. So, even though a Type is a MemberInfo so that Type.GetMember and Type.GetMembers can return Type instances , the Type class is more important than the other MemberInfo classes, and has a short name in the System...

VCLtoFCL

Just as WinForms' ShowDialog is almost identical to Delphi's ShowModal, there are several common VCL features that are almost identical to WinForms features, but which are located in different classes or have different names under WinForms. Table 15-1 contains the most commonly used features, with their WinForms equivalents. I cover the differences between Delphi's TCanvas and .NET's Graphics in the next chapter. Table 15-1. FCL Equivalents for Common VCL Constructs Application.ProcessMessages...