Top Banner
Appendixes PART 8
88

Appendixes - Springer

May 12, 2023

Download

Documents

Khang Minh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Appendixes - Springer

Appendixes

P A R T 8

Page 2: Appendixes - Springer

COM and .NET Interoperability

The goal of this book was to provide you with a solid foundation in the C# language and the coreservices provided by the .NET platform. I suspect that when you contrast the object model providedby .NET to that of Microsoft’s previous component architecture (COM), you’ll no doubt be con-vinced that these are two entirely unique systems. Regardless of the fact that COM is now consideredto be a legacy framework, you may have existing COM-based systems that you would like to inte-grate into your new .NET applications.

Thankfully, the .NET platform provides various types, tools, and namespaces that make theprocess of COM and .NET interoperability quite straightforward. This appendix begins by examin-ing the process of .NET to COM interoperability and the related Runtime Callable Wrapper (RCW).The latter part of this appendix examines the opposite situation: a COM type communicating witha .NET type using a COM Callable Wrapper (CCW).

■Note A full examination of the .NET interoperability layer would require a book unto itself. If you require moredetails than presented in this appendix, check out my book COM and .NET Interoperability (Apress, 2002).

The Scope of .NET InteroperabilityRecall that when you build assemblies using a .NET-aware compiler, you are creating managed codethat can be hosted by the common language runtime (CLR). Managed code offers a number of ben-efits such as automatic memory management, a unified type system (the CTS), self-describingassemblies, and so forth. As you have also seen, .NET assemblies have a particular internal compo-sition. In addition to CIL instructions and type metadata, assemblies contain a manifest that fullydocuments any required external assemblies as well as other file-related details (strong naming,version number, etc.).

On the other side of the spectrum are legacy COM servers (which are, of course, unmanagedcode). These binaries bear no relationship to .NET assemblies beyond a shared file extension (*.dllor *.exe). First of all, COM servers contain platform-specific machine code, not platform-agnosticCIL instructions, and work with a unique set of data types (often termed oleautomation or variant-compliant data types), none of which are directly understood by the CLR.

In addition to the necessary COM-centric infrastructure required by all COM binaries (suchas registry entries and support for core COM interfaces like IUnknown) is the fact that COM typesdemand to be reference counted in order to correctly control the lifetime of a COM object. This is instark contrast, of course, to a .NET object, which is allocated on a managed heap and handled bythe CLR garbage collector.

Given that .NET types and COM types have so little in common, you may wonder how thesetwo architectures can make use of each others’ services. Unless you are lucky enough to work for a 1283

A P P E N D I X A

Page 3: Appendixes - Springer

company dedicated to “100% Pure .NET” development, you will most likely need to build .NETsolutions that use legacy COM types. As well, you may find that a legacy COM server might like tocommunicate with the types contained within a shiny new .NET assembly.

The bottom line is that for some time to come, COM and .NET must learn how to get along.This appendix examines the process of managed and unmanaged types living together in harmonyusing the .NET interoperability layer. In general, the .NET Framework supports two core flavors ofinteroperability:

• .NET applications using COM types

• COM applications using .NET types

As you’ll see throughout this appendix, the .NET Framework 3.5 SDK and Visual Studio 2008supply a number of tools that help bridge the gap between these unique architectures. As well, the.NET base class library defines a namespace (System.Runtime.InteropServices) dedicated solely tothe issue of interoperability. However, before diving in too far under the hood, let’s look at a verysimple example of a .NET class communicating with a COM server.

■Note The .NET platform also makes it very simple for a .NET assembly to call into the underlying API of theoperating system (as well as any C-based unmanaged *.dll) using a technology termed platform invocation(or simply PInvoke). From a C# point of view, working with PInvoke involves at absolute minimum applying the[DllImport] attribute to the external method to be executed. Although PInvoke is not examined in this appendix,check out the [DllImport] attribute using the .NET Framework 3.5 SDK documentation for further details.

A Simple Example of .NET to COM InteropTo begin our exploration of interoperability services, let’s see just how simple things appear on thesurface. The goal of this section is to build a Visual Basic 6.0 ActiveX *.dll server, which is then con-sumed by a C# application.

■Note There are many COM frameworks in existence beyond VB6 (such as the Active Template Library [ATL] andthe Microsoft Foundation Classes [MFC]). VB6 has been chosen to build the COM servers in this appendix, as itprovides the most user-friendly syntax to build COM applications. Feel free to make use of ATL/MFC if you sochoose.

Fire up VB6, and create a new ActiveX *.dll project named SimpleComServer, rename your ini-tial class file to ComCalc.cls, and name the class itself ComCalc. As you may know, the name of yourproject and the names assigned to the contained classes will be used to define the programmaticidentifier (ProgID) of the COM types (SimpleComServer.ComCalc, in this case). Finally, define the fol-lowing methods within ComCalc.cls:

' The VB6 COM objectOption Explicit

Public Function Add(ByVal x As Integer, ByVal y As Integer) As IntegerAdd = x + y

End Function

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1284

Page 4: Appendixes - Springer

Public Function Subtract(ByVal x As Integer, ByVal y As Integer) As IntegerSubtract = x - y

End Function

At this point, compile your *.dll (via the File ➤ Make menu option) and, just to keep thingspeaceful in the world of COM, establish binary compatibility (via the Component tab of the pro-ject’s Property page) before you exit the VB6 IDE. This will ensure that if you recompile the appli-cation, VB6 will preserve the assigned globally unique identifiers (GUIDs).

■Source Code The SimpleComServer project is located under the Appendix A subdirectory.

Building the C# ClientNow open up Visual Studio 2008 and create a new C# Console Application named CSharpComClient.When you are building a .NET application that needs to communicate with a legacy COM applica-tion, the first step is to reference the COM server within your project (much like you reference a.NET assembly).

To do so, simply access the Project ➤ Add Reference menu selection and select the COM tabfrom the Add Reference dialog box. The name of your COM server will be listed alphabetically, asthe VB6 compiler updated the system registry with the necessary listings when you compiledyour project. Go ahead and select the SimpleComServer.dll as shown in Figure A-1 and close thedialog box.

Figure A-1. Referencing a COM server using Visual Studio 2008

Now, if you examine the References folder of the Solution Explorer, you see what looks to be anew .NET assembly reference added to your project, as illustrated in Figure A-2. Formally speaking,assemblies that are generated when referencing a COM server are termed interop assemblies. With-out getting too far ahead of ourselves at this point, simply understand that interop assembliescontain .NET descriptions of COM types.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1285

Page 5: Appendixes - Springer

Figure A-2. The referenced interop assembly

Although we have not added any code to our initial C# class type, if you compile your applica-tion and examine the project’s bin\Debug directory, you will find that a local copy of the generatedinterop assembly has been placed in the application directory (see Figure A-3). Notice that VisualStudio 2008 automatically prefixes Interop. to interop assemblies generated when using the AddReference dialog box—however, this is only a convention; the CLR does not demand that interopassemblies follow this particular naming convention.

Figure A-3. The autogenerated interop assembly

To complete this initial example, update the Main() method of your initial class to invoke theAdd() method from a ComCalc object and display the result. For example:

using System;using SimpleComServer;

namespace CSharpComClient{class Program{static void Main(string[] args){

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1286

Page 6: Appendixes - Springer

Console.WriteLine("***** The .NET COM Client App *****");ComCalc comObj = new ComCalc();Console.WriteLine("COM server says 10 + 832 is {0}",comObj.Add(10, 832));

Console.ReadLine();}

}}

As you can see from the previous code example, the namespace that contains the ComCalc COMobject is named identically to the original VB6 project (notice the using statement). The output shownin Figure A-4 is as you would expect.

Figure A-4. Behold! .NET to COM interoperability

As you can see, consuming a COM type from a .NET application can be a very transparentoperation indeed. As you might imagine, however, a number of details are occurring behind thescenes to make this communication possible, the gory details of which you will explore throughoutthis appendix, beginning with taking a deeper look into the interop assembly itself.

Investigating a .NET Interop AssemblyAs you have just seen, when you reference a COM server using the Visual Studio 2008 Add Referencedialog box, the IDE responds by generating a brand-new .NET assembly taking an Interop. prefix(such as Interop.SimpleComServer.dll). Just like an assembly that you would create yourself,interop assemblies contain type metadata, an assembly manifest, and under some circumstancesmay contain CIL code. As well, just like a “normal” assembly, interop assemblies can be deployedprivately (e.g., within the directory of the client assembly) or assigned a strong name to be deployedto the GAC.

Interop assemblies are little more than containers to hold .NET metadata descriptions of theoriginal COM types. In many cases, interop assemblies do not contain CIL instructions to imple-ment their methods, as the real work is taking place in the COM server itself. The only time aninterop assembly contains executable CIL instructions is if the COM server contains COM objectsthat have the ability to fire events to the client. In this case, the CIL code within the interop assem-bly is used by the CLR to translate the event-handling logic from COM connection points into .NETdelegates.

At first glance, it may seem that interop assemblies are not entirely useful, given that they donot contain any implementation logic. However, the metadata descriptions within an interopassembly are extremely important, as it will be consumed by the CLR at runtime to build a runtimeproxy (termed the Runtime Callable Wrapper, or simply RCW) that forms a bridge between the .NETapplication and the COM object it is communicating with.

You’ll examine the details of the RCW in the next several sections; however, for the time being,open up the Interop.SimpleComServer.dll assembly using ildasm.exe, as you see in Figure A-5.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1287

Page 7: Appendixes - Springer

Figure A-5. The guts of the Interop.SimpleComServer.dll interop assembly

As you can see, although the original VB6 project only defined a single COM class (ComCalc), theinterop assembly contains three types. This can also be verified using the VS 2008 Object Browser(see Figure A-6).

Figure A-6. Hmm, how does a single COM type yield three .NET types?

Simply put, each COM class is represented by three distinct .NET types. First, you have a .NETtype that is identically named to the original COM type (ComCalc, in this case). Next, you have a sec-ond .NET type that takes a Class suffix (ComCalcClass). These types are very helpful when you havea COM type that implements several custom interfaces, in that the Class-suffixed types expose allmembers from each interface supported by the COM type. Thus, from a .NET programmer’s pointof view, there is no need to manually obtain a reference to a specific COM interface before invokingits functionality. Although ComCalc did not implement multiple custom interfaces, we are able toinvoke the Add() and Subtract() methods from a ComCalcClass object (rather than a ComCalc object)as follows:

static void Main(string[] args){Console.WriteLine("***** The .NET COM Client App *****");

// Now using the Class-suffixed type.ComCalcClass comObj = new ComCalcClass();Console.WriteLine("COM server says 10 + 832 is {0}",comObj.Add(10, 832));

Console.ReadLine();}

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1288

Page 8: Appendixes - Springer

Finally, interop assemblies define .NET equivalents of any original COM interfaces definedwithin the COM server. In this case, we find a .NET interface named _ComCalc. Unless you are wellversed in the mechanics of VB6 COM, this is certain to appear strange, given that we never directlycreated an interface in our SimpleComServer project (let alone the oddly named _ComCalc inter-face). The role of these underscore-prefixed interfaces will become clear as you move throughoutthis appendix; for now, simply know that if you really wanted to, you could make use of interface-based programming techniques to invoke Add() or Subtract():

static void Main(string[] args){Console.WriteLine("***** The .NET COM Client App *****");

// Now manually obtain the hidden interface.ComCalc itfComInterface = null;ComCalcClass comObj = new ComCalcClass();itfComInterface = (_ComCalc)comObj;

Console.WriteLine("COM server says 10 + 832 is {0}",itfComInterface.Add(10, 832));

Console.ReadLine();}

Now, do understand that invoking a method using the Class-suffixed or underscore-prefixedinterface is seldom necessary. However, as you build more complex .NET applications that need towork with COM types in more sophisticated manners, having knowledge of these types is critical.

■Source Code The CSharpComClient project is located under the Appendix A subdirectory.

Understanding the Runtime Callable WrapperAs mentioned, at runtime the CLR will make use of the metadata contained within a .NET interopassembly to build a proxy type that will manage the process of .NET to COM communication. Theproxy to which I am referring is the Runtime Callable Wrapper, which is little more than a bridge tothe real COM class (officially termed a coclass). Every coclass accessed by a .NET client requires acorresponding RCW. Thus, if you have a single .NET application that uses three COM coclasses, youend up with three distinct RCWs that map .NET calls into COM requests. Figure A-7 illustrates thebig picture.

■Note There is always a single RCW per COM object, regardless of how many interfaces the .NET client hasobtained from the COM type (you’ll examine a multi-interfaced VB6 COM object a bit later in this appendix). Usingthis technique, the RCW can maintain the correct COM identity (and reference count) of the COM object.

Again, the good news is that the RCW is created automatically when required by the CLR. Theother bit of good news is that legacy COM servers do not require any modifications to be consumedby a .NET-aware language. The intervening RCW takes care of the internal work. To see how this isachieved, let’s formalize some core responsibilities of the RCW.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1289

Page 9: Appendixes - Springer

Figure A-7. RCWs sit between the .NET caller and the COM object.

The RCW: Exposing COM Types As .NET TypesThe RCW is in charge of transforming COM data types into .NET equivalents (and vice versa). As asimple example, assume you have a VB6 COM subroutine defined as follows:

' VB6 COM method definition.Public Sub DisplayThisString(ByVal s as String)

The interop assembly defines the method parameter as a .NET System.String:

' C# mapping of COM method.public void DisplayThisString(string s)

When this method is invoked by the .NET code base, the RCW automatically takes the incom-ing System.String and transforms it into a VB6 String data type (which, as you may know, is in facta COM BSTR). As you would guess, all COM data types have a corresponding .NET equivalent. Tohelp you gain your bearings, Table A-1 documents the mapping taking place between COM IDL(interface definition language) data types, the related .NET System data types, and the correspon-ding C# keyword (if applicable).

Table A-1. Mapping Intrinsic COM Types to .NET Types

COM IDL Data Type System Types C# Keyword

wchar_t, short System.Int16 short

long, int System.Int32 int

Hyper System.Int64 long

unsigned char, byte System.Byte byte

single System.Single -

double System.Double double

VARIANT_BOOL System.Boolean bool

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1290

Page 10: Appendixes - Springer

COM IDL Data Type System Types C# Keyword

BSTR System.String string

VARIANT System.Object object

DECIMAL System.Decimal -

DATE System.DateTime -

GUID System.Guid -

CURRENCY System.Decimal -

IUnknown System.Object object

IDispatch System.Object object

The RCW: Managing a Coclass’s Reference CountAnother important duty of the RCW is to manage the reference count of the COM object. As youmay know from your experience with COM, the COM reference-counting scheme is a joint venturebetween coclass and client and revolves around the proper use of AddRef() and Release() calls.COM objects self-destruct when they detect that they have no outstanding references.

However, .NET types do not use the COM reference-counting scheme, and therefore a .NETclient should not be forced to call Release() on the COM types it uses. To keep each participanthappy, the RCW caches all interface references internally and triggers the final release when thetype is no longer used by the .NET client. The bottom line is that similar to VB6, .NET clients neverexplicitly call AddRef(), Release(), or QueryInterface().

■Note If you wish to directly interact with a COM object’s reference count from a .NET application, the System.Runtime.InteropServices namespace provides a type named Marshal. This class defines a number of staticmethods, many of which can be used to manually interact with a COM object’s lifetime. Although you will typicallynot need to make use of Marshal in most of your applications, consult the .NET Framework 3.5 SDK documenta-tion for further details.

The RCW: Hiding Low-Level COM InterfacesThe final core service provided by the RCW is to consume a number of low-level COM interfaces.Because the RCW tries to do everything it can to fool the .NET client into thinking it is directly com-municating with a native .NET type, the RCW must hide various low-level COM interfaces fromview.

For example, when you build a COM class that supports IConnectionPointContainer (andmaintains a subobject or two supporting IConnectionPoint), the coclass in question is able to fireevents back to the COM client. VB6 hides this entire process from view using the Event andRaiseEvent keywords. In the same vein, the RCW also hides such COM “goo” from the .NET client.Table A-2 outlines the role of these hidden COM interfaces consumed by the RCW.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1291

Page 11: Appendixes - Springer

Table A-2. Hidden COM Interfaces

Hidden COM Interface Meaning in Life

IConnectionPointContainer Enable a coclass to send events back to an interested client. IConnectionPoint VB6 automatically provides a default implementation of each of

these interfaces.

IDispatch Facilitate “late binding” to a coclass. Again, when you are IProvideClassInfo building VB6 COM types, these interfaces are automatically

supported by a given COM type.

IErrorInfo These interfaces enable COM clients and COM objects to send ISupportErrorInfo and respond to COM errors.ICreateErrorInfo

IUnknown The granddaddy of COM. Manages the reference count of theCOM object and allows clients to obtain interfaces from thecoclass.

The Role of COM IDLAt this point, you hopefully have a solid understanding of the role of the interop assembly andthe RCW. Before you go much further into the COM to .NET conversion process, it is necessary toreview some of the finer details of COM IDL. Understand, of course, that this appendix is notintended to function as a complete COM IDL tutorial; however, to better understand the interoplayer, you only need to be aware of a few IDL constructs.

All .NET assemblies contain metadata. Formally speaking, metadata is used to describe eachand every aspect of a .NET assembly, including the internal types (their members, base class, and soon), assembly version, and optional assembly-level information (strong name, culture, and so on).

In many ways, .NET metadata is the big brother of an earlier metadata format used to describeclassic COM servers. Classic ActiveX COM servers (*.dlls or *.exes) document their internal typesusing a type library, which may be realized as a stand-alone *.tlb file or bundled into the COMserver as an internal resource (which is the default behavior of VB6). COM type libraries are typi-cally created using a metadata language called the Interface Definition Language and a specialcompiler named midl.exe (the Microsoft IDL compiler).

VB6 does a fantastic job of hiding type libraries and IDL from view. In fact, many skilled VBCOM programmers can live a happy and productive life ignoring the syntax of IDL altogether.Nevertheless, whenever you compile ActiveX project workspace types, VB automatically generatesand embeds the type library within the physical *.dll or *.exe COM server. Furthermore, VB6ensures that the type library is automatically registered under a very particular part of the systemregistry: HKEY_CLASSES_ROOT\TypeLib (see Figure A-8).

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1292

Page 12: Appendixes - Springer

Figure A-8. HKCR\TypeLib lists all registered type libraries on a given machine.

Type libraries are referenced all the time by numerous IDEs. For example, whenever you accessthe Project ➤ References menu selection of VB6, the IDE consults HKCR\TypeLib to determine eachand every registered type library, as shown in Figure A-9.

Figure A-9. Referencing COM type information from VB6

Likewise, when you open the VB6 Object Browser, the VB6 IDE reads the type information anddisplays the contents of the COM server using a friendly GUI, as shown in Figure A-10.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1293

Page 13: Appendixes - Springer

Figure A-10. Viewing type libraries using the VB6 Object Browser

Observing the Generated IDL for Your VB COM ServerAlthough the VB6 Object Browser displays all COM types contained within a type library, the OLEView utility (oleview.exe) allows you to view the underlying IDL syntax used to build the correspon-ding type library. If you have installed Visual Basic 6.0, you can open OLE View via Start ➤ AllPrograms ➤ Microsoft Visual Studio 6.0 ➤ Microsoft Visual Studio 6.0 Tools and locate the Simple-ComServer server under the Type Libraries node of the tree view control, as shown in Figure A-11.

Figure A-11. Hunting down SimpleComServer using the OLE/COM object viewer

If you were to double-click the type library icon, you would open a new window that shows youall of the IDL tokens that constitute the type library generated by the VB6 compiler. Here is the rele-vant—and slightly reformatted—IDL (your [uuid] values will differ):

[uuid(8AED93CB-7832-4699-A2FC-CAE08693E720), version(1.0)]library SimpleComServer{importlib("stdole2.tlb");interface _ComCalc;

[odl, uuid(5844CD28-2075-4E77-B619-9B65AA0761A3), version(1.0),hidden, dual, nonextensible, oleautomation]interface _ComCalc : IDispatch {[id(0x60030000)]

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1294

Page 14: Appendixes - Springer

HRESULT Add([in] short x, [in] short y, [out, retval] short* );[id(0x60030001)]HRESULT Subtract([in] short x, [in] short y, [out, retval] short* );};

[uuid(012B1485-6834-47FF-8E53-3090FE85050C), version(1.0)]coclass ComCalc {

[default] interface _ComCalc;};

};

IDL AttributesTo begin parsing out this IDL, notice that IDL syntax contains blocks of code placed in squarebrackets ([...]). Within these brackets is a comma-delimited set of IDL keywords, which are usedto disambiguate the “very next thing” (the item to the right of the block or the item directly belowthe block). These blocks are IDL attributes that serve the same purpose as .NET attributes (i.e., theydescribe something). One key IDL attribute is [uuid], which is used to assign the GUID of a givenCOM type. As you may already know, just about everything in COM is assigned a GUID (interfaces,COM classes, type libraries, and so on), which is used to uniquely identify a given item.

The IDL Library StatementStarting at the top, you have the COM library statement, which is marked using the IDL library key-word. Contained within the library statement are each and every interface and COM class, and anyenumeration and user-defined type. In the case of SimpleComServer, the type library lists exactlyone COM class, ComCalc, which is marked using the coclass (i.e., COM class) keyword.

The Role of the [default] InterfaceAccording to the laws of COM, the only possible way in which a COM client can communicate witha COM class is to use an interface reference (not an object reference). If you have created C++-basedCOM clients, you are well aware of the process of querying for a given interface, releasing the inter-face when it is no longer used, and so forth. However, when you make use of VB6 to build COMclients, you receive a default interface on the COM class automatically.

When you build VB6 COM servers, any public member on a *.cls file (such as your Add() func-tion) is placed onto the “default interface” of the COM class. Now, if you examine the class definitionof ComCalc, you can see that the name of the default interface is _ComCalc:

[uuid(012B1485-6834-47FF-8E53-3090FE85050C), version(1.0)]coclass ComCalc {[default] interface _ComCalc;

};

In case you are wondering, the name of the default interface VB6 constructs in the backgroundis always _NameOfTheClass (the underscore is a naming convention used to specify a hidden inter-face). Thus, if you have a class named Car, the default interface is _Car, a class named DataConnectorhas a default interface named _DataConnector, and so forth.

Under VB6, the default interface is completely hidden from view. However, when you write thefollowing VB6 code:

' VB 6.0 COM client code.Dim c As ComCalcSet c = New ComCalc ' [default] _ComCalc interface returned automatically!

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1295

Page 15: Appendixes - Springer

the VB runtime automatically queries the object for the default interface (as specified by the typelibrary) and returns it to the client. Because VB always returns the default interface on a COM class,you can pretend that you have a true object reference. However, this is only a bit of syntactic sugarprovided by VB6. In COM, there is no such thing as a direct object reference. You always have aninterface reference (even if it happens to be the default).

The Role of IDispatchIf you examine the IDL description of the default _ComCalc interface, you see that this interfacederives from a standard COM interface named IDispatch. While a full discussion concerning therole of IDispatch is well outside of the scope of this appendix, simply understand that this is theinterface that makes it possible to interact with COM objects on the Web from within a classicActive Server Page, as well as anywhere else where late binding is required.

IDL Parameter AttributesThe final bit of IDL that you need to be aware of is how VB6 parameters are expressed under thehood. Under VB6 all parameters are passed by reference, unless the ByVal keyword is used explicitly,which is represented using the IDL [in] attribute. Furthermore, a function’s return value is markedusing the [out, retval] attributes. Thus, the following VB6 function:

' VB6 functionPublic Function Add(ByVal x as Integer, ByVal y as Integer) as IntegerAdd = x + y

End Function

would be expressed in IDL like so:

HRESULT Add([in] short* x, [in] short* y, [out, retval] short*);

On the other hand, if you do not mark a parameter using the VB6 ByVal keyword, ByRef isassumed:

' These parameters are passed ByRef under VB6!Public Function Subtract(x As Integer, y As Integer) As IntegerSubtract = x - y

End Function

ByRef parameters are marked in IDL via the [in, out] attributes:

HRESULT Subtract([in, out] short x, [in, out] short y, [out, retval] short*);

Using a Type Library to Build an Interop AssemblyTo be sure, the VB6 compiler generates many other IDL attributes under the hood, and you will seeadditional bits and pieces where appropriate. However, at this point, I am sure you are wonderingexactly why I spent the last several pages describing COM IDL. The reason is simple: when you adda reference to a COM server using Visual Studio 2008, the IDE reads the type library to build thecorresponding interop assembly. While VS 2008 does a very good job of generating an interopassembly, the Add Reference dialog box follows a default set of rules regarding how the interopassembly will be constructed and does not allow you to fine-tune this construction.

If you require a greater level of flexibility, you have the option of generating interop assembliesat the command prompt, using a .NET tool named tlbimp.exe (the type library importer utility).Among other things, tlbimp.exe allows you to control the name of the .NET namespace that will

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1296

Page 16: Appendixes - Springer

contain the types and the name of the output file. Furthermore, if you wish to assign a strong nameto your interop assembly in order to deploy it to the GAC, tlbimp.exe provides the /keyfile flag tospecify the *.snk file (see Chapter 15 for details regarding strong names). To view all of your options,simply type tlbimp at a Visual Studio 2008 command prompt and hit the Enter key, as shown inFigure A-12.

Figure A-12. Options of tlbimp.exe

While this tool has numerous options, the following command could be used to generate astrongly named interop assembly (assuming you have generated a *.snk file named myKeyPair.snk)named CalcInteropAsm.dll:

tlbimp SimpleComServer.dll /keyfile:myKeyPair.snk /out:CalcInteropAsm.dll

Again, if you are happy with the interop assembly created by Visual Studio 2008, you are notrequired to directly make use of tlbimp.exe.

Late Binding to the CoCalc CoclassOnce you have generated an interop assembly, your .NET applications are now able to make use oftheir types using early binding or late binding techniques. Given that you have already seen how tocreate a COM type using early binding at the opening of this appendix (via the C# new keyword), let’sturn our attention to activating a COM object using late binding.

As you recall from Chapter 16, the System.Reflection namespace provides a way for you toprogrammatically inspect the types contained in a given assembly at runtime. In COM, the samesort of functionality is supported through the use of a set of standard interfaces (e.g., ITypeLib,ITypeInfo, and so on). When a client binds to a member at runtime (rather than at compile time),the client is said to exercise “late” binding.

By and large, you should always prefer the early binding technique using the C# new keyword.There are times, however, when you must use late binding to a coclass. For example, some legacyCOM servers may have been constructed in such a way that they provide no type informationwhatsoever. If this is the case, it should be clear that you cannot run the tlbimp.exe utility in thefirst place. For these rare occurrences, you can access classic COM types using .NET reflectionservices.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1297

Page 17: Appendixes - Springer

The process of late binding begins with a client obtaining the IDispatch interface from a givencoclass. This standard COM interface defines a total of four methods, only two of which you need toconcern yourself with at the moment. First, you have GetIDsOfNames(). This method allows a callerto use late binding by obtaining the numerical value (called the dispatch ID, or DISPID) used toidentify the method it is attempting to invoke.

In COM IDL, a member’s DISPID is assigned using the [id] attribute. If you examine the IDLcode generated by VB6 (using the OLE View tool), you will see that the DISPID of the Add() methodhas been assigned a DISPID such as the following:

[id(0x60030000)] HRESULT Add( [in] short x, [in] short y, [out, retval] short* );

This is the value that GetIDsOfNames() returns to the late-bound client. Once the client obtainsthis value, it makes a call to the next method of interest, Invoke(). This method of IDispatch takes anumber of arguments, one of which is the DISPID obtained using GetIDsOfNames(). In addition, theInvoke() method takes an array of COM VARIANT types that represent the parameters passed to thefunction. In the case of the Add() method, this array contains two shorts (of some value). The finalargument of Invoke() is another VARIANT that holds the return value of the method invocation(again, a short).

Although a .NET client using late binding does not directly use the IDispatch interface, thesame general functionality comes through using the System.Reflection namespace. To illustrate,the following is another C# client that uses late binding to trigger the Add() logic. Notice that thisapplication does not make reference to the assembly in any way and therefore does not require theuse of the tlbimp.exe utility.

// Be sure to use the System.Reflection namespace.static void Main(string[] args){Console.WriteLine("***** The Late Bound .NET Client *****");

// First get IDispatch reference from coclass.Type calcObj =Type.GetTypeFromProgID("SimpleCOMServer.ComCalc");

object calcDisp = Activator.CreateInstance(calcObj);

// Make the array of args.object[] addArgs = { 100, 24 };

// Invoke the Add() method and obtain summation.object sum = null;sum = calcObj.InvokeMember("Add", BindingFlags.InvokeMethod,null, calcDisp, addArgs);

// Display result.Console.WriteLine("Late bound adding: 100 + 24 is: {0}", sum);Console.ReadLine();

}

■Source Code The CSharpComLateBinding application is included under the Appendix A subdirectory.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1298

Page 18: Appendixes - Springer

Building a More Elaborate COM ServerSo much for Math 101. It’s time to build a VB6 ActiveX server that makes use of more elaborate COMprogramming techniques. Create a brand-new ActiveX *.dll workspace named Vb6ComCarServer.Rename your initial class to CoCar, which is implemented like so:

Option Explicit

' A COM enum.Enum CarTypeViperColtBMW

End Enum

' A COM Event.Public Event BlewUp()

' Member variables.Private currSp As IntegerPrivate maxSp As IntegerPrivate Make As CarType

' Remember! All Public members' are exposed by the default interface!Public Property Get CurrentSpeed() As IntegerCurrentSpeed = currSp

End Property

Public Property Get CarMake() As CarTypeCarMake = Make

End Property

Public Sub SpeedUp()currSp = currSp + 10If currSp >= maxSp ThenRaiseEvent BlewUp ' Fire event if you max out the engine.

End IfEnd Sub

Private Sub Class_Initialize()MsgBox "Init COM car"

End Sub

Public Sub Create(ByVal max As Integer, _ByVal cur As Integer, ByVal t As CarType)maxSp = maxcurrSp = curMake = t

End Sub

As you can see, this is a simple COM class that mimics the functionality of the C# Car class usedthroughout this text. The only point of interest is the Create() subroutine, which allows the caller topass in the state data representing the Car object.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1299

Page 19: Appendixes - Springer

Supporting an Additional COM InterfaceNow that you have fleshed out the details of building a COM class with a single (default) interface,insert a new *.cls file that defines the following IDriverInfo interface:

Option Explicit

' Driver has a namePublic Property Let DriverName(ByVal s As String)End PropertyPublic Property Get DriverName() As StringEnd Property

If you have created COM objects supporting multiple interfaces, you are aware that VB6provides the Implements keyword. Once you specify the interfaces implemented by a given COMclass, you are able to make use of the VB6 code window to build the method stubs. Assume youhave added a private String variable (driverName) to the CoCar class type and implemented theIDriverInfo interface as follows:

' Implemented interfaces' [General][Declarations]Implements IDriverInfo...' ***** IDriverInfo impl ***** 'Private Property Let IDriverInfo_DriverName(ByVal RHS As String)driverName = RHS

End Property

Private Property Get IDriverInfo_DriverName() As StringIDriverInfo_driverName = driverName

End Property

To wrap up this interface implementation, set the Instancing property of IDriverInfo toPublicNotCreatable (given that the outside world should not be able to allocate interface types).

Exposing an Inner ObjectUnder VB6 (as well as COM itself), we do not have the luxury of classical implementation inheritance.Rather, we’re limited to the use of the containment/delegation model (the “has-a” relationship).For testing purposes, add a final *.cls file to your current VB6 project named Engine, and set itsinstancing property to PublicNotCreatable (as you want to prevent the user from directly creatingan Engine object).

The default public interface of Engine is short and sweet. Define a single function that returnsan array of strings to the outside world representing pet names for each cylinder of the engine(okay, no right-minded person gives friendly names to his or her cylinders, but hey . . .):

Option Explicit

Public Function GetCylinders() As String()Dim c(3) As Stringc(0) = "Grimey"c(1) = "Thumper"c(2) = "Oily"c(3) = "Crusher"GetCylinders = c

End Function

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1300

Page 20: Appendixes - Springer

Finally, add a method to the default interface of CoCar named GetEngine(), which returns aninstance of the contained Engine (I assume you will create a Private member variable named eng oftype Engine for this purpose):

' Return the Engine to the world.Public Function GetEngine() As EngineSet GetEngine = eng

End Function

At this point, you have an ActiveX server that contains a COM class supporting two interfaces.As well, you are able to return an internal COM type using the [default] interface of the CoCar andinteract with some common programming constructs (enums and COM arrays). Go ahead andcompile your sever (setting binary compatibility, once finished), and then close down your currentVB6 workspace.

■Source Code The Vb6ComCarServer project is included under the Appendix A subdirectory.

Examining the Interop AssemblyRather than making use of the tlbimp.exe utility to generate our interop assembly, simply create anew console project (named CSharpCarClient) using Visual Studio 2008 and set a reference to theVb6ComCarServer.dll using the COM tab of the Add Reference dialog box. Now, examine the interopassembly using the VS 2008 Object Browser utility, as shown in Figure A-13.

Figure A-13. The Interop.VbComCarServer.dll assembly

Once again we have a number of Class-suffixed and underscore-prefixed interface types,as well as a number of new items we have not yet examined, whose names suggest they may beused to handle COM to .NET event notifications (__CoCar_Event, __CoCar_SinkHelper, and __CoCarBlewUpEventHandler in particular). Recall from earlier in this appendix, I mentioned that

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1301

Page 21: Appendixes - Springer

when a COM object exposes COM events, the interop assembly will contain additional CIL codethat is used by the CLR to map COM events to .NET events (you’ll see them in action in just a bit).

Building Our C# Client ApplicationGiven that the CLR will automatically create the necessary RCW at runtime, our C# application canprogram directly against the CoCar, CarType, Engine, and IDriveInfo types as if they were all imple-mented using managed code. Here is the complete implementation, with analysis to follow:

// Be sure to import the Vb6ComCarServer namespace.class Program{static void Main(string[] args){Console.WriteLine("***** CoCar Client App *****");

// Create the COM class using early binding.CoCar myCar = new CoCar();

// Handle the BlewUp event.myCar.BlewUp += new __CoCar_BlewUpEventHandler(myCar_BlewUp);

// Call the Create() method.myCar.Create(50, 10, CarType.BMW);

// Set name of driver.IDriverInfo itf = (IDriverInfo)myCar;itf.DriverName = "Fred";Console.WriteLine("Drive is named: {0}", itf.DriverName);

// Print type of car.Console.WriteLine("Your car is a {0}.", myCar.CarMake);Console.WriteLine();

// Get the Engine and print name of the cylinders.Engine eng = myCar.GetEngine();Console.WriteLine("Your Cylinders are named:");string[] names = (string[])eng.GetCylinders();foreach (string s in names){Console.WriteLine(s);

}Console.WriteLine();

// Speed up car to trigger event.for (int i = 0; i < 5; i++){myCar.SpeedUp();

}}

// Handler for the BlewUp event.static void myCar_BlewUp(){Console.WriteLine("Your car is toast!");

}}

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1302

Page 22: Appendixes - Springer

Notice that when we call GetCylinders(), we are casting the return value into an array ofstrings. The reason is the fact that COM arrays are (most often) represented by the SAFEARRAY COMtype (which is always the case when building COM applications using VB6). The RCW will mapSAFEARRAY types into a System.Array object, rather than automatically mapping SAFEARRAYs into anarray represented with C# syntax. Thus, by casting the Array object into a string[], we can processthe array more naturally.

Interacting with the CoCar TypeRecall that when we created the VB6 CoCar, we defined and implemented a custom COM interfacenamed IDriverInfo, in addition to the automatically generated default interface (_CoCar) created bythe VB6 compiler. When our Main() method creates an instance of CoCar, we only have direct accessto the members of the _CoCar interface, which as you recall will be composed by each public mem-ber of the COM class:

// Here, you are really working with the [default] interface.myCar.Create(50, 10, CarType.BMW);

Given this fact, in order to invoke the DriverName property of the IDriverInfo interface, wemust explicitly cast the CoCar object to an IDriverInfo interface as follows:

// Set name of driver.IDriverInfo itf = (IDriverInfo)myCar;itf.DriverName = "Fred";Console.WriteLine("Drive is named: {0}", itf.DriverName);

Recall, however, that when a type library is converted into an interop assembly, it will containClass-suffixed types that expose every member of every interface. Therefore, if you so choose, youcould simplify your programming if you create and make use of a CoCarClass object, rather than aCoCar object. For example, consider the following subroutine, which makes use of members of thedefault interface of CoCar as well as members of IDriverInfo:

static void UseCar(){// -Class suffix types expose all// members from all interfaces.CoCarClass c = new CoCarClass();

// This property is a member of IDriverInfo.c.DriverName = "Mary";

// This method is a member of _CoCar.c.SpeedUp();

}

If you are wondering exactly how this single type is exposing members of each implementedinterface, check out the list of implemented interfaces and the base class of CoCarClass using theVisual Studio 2008 Object Browser (see Figure A-14).

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1303

Page 23: Appendixes - Springer

Figure A-14. The composition of CoCarClass

As you can see, this type implements the _CoCar and _IDriverInfo interfaces and exposes themas “normal” public members.

Intercepting COM EventsIn Chapter 11, you learned about the .NET event model. Recall that this architecture is based ondelegating the flow of logic from one part of the application to another. The entity in charge of for-warding a request is a type deriving from System.MulticastDelegate, which we create indirectly inC# using the delegate keyword.

When the tlbimp.exe utility encounters event definitions in the COM server’s type library, itresponds by creating a number of managed types that wrap the low-level COM connection pointarchitecture. Using these types, you can pretend to add a member to a System.MulticastDelegate’sinternal list of methods. Under the hood, of course, the proxy is mapping the incoming COM eventto their managed equivalents. Table A-3 briefly describes these types.

Table A-3. COM Event Helper Types

Generated Type (Based on the _CarEvents [source] Interface) Meaning in Life

__CoCar_Event This is a managed interface that defines the add and removemembers used to add (or remove) a method to (or from) theSystem.MulticastDelegate’s linked list.

__CoCar_BlewUpEventHandler This is the managed delegate (which derives fromSystem.MulticastDelegate).

__CoCar_SinkHelper This generated class implements the outbound interface in a.NET-aware sink object.

As you would hope, you are able to handle the incoming COM events in the same way youhandle events based on the .NET delegation architecture:

class Program{static void Main(string[] args){Console.WriteLine("***** CoCar Client App *****");CoCar myCar = new CoCar();

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1304

Page 24: Appendixes - Springer

// Handle the BlewUp event.myCar.BlewUp += new __CoCar_BlewUpEventHandler(myCar_BlewUp);...

}

// Handler for the BlewUp event.static void myCar_BlewUp(){Console.WriteLine("Your car is toast!");

}}

It is also worth pointing out if your C# code base is able to make use of all of the event-centricnotations (anonymous methods, method group conversion, lambda expressions, etc.) when inter-cepting events from COM objects.

■Source Code The CSharpCarClient project is included under the Appendix A subdirectory.

That wraps up our investigation of how a .NET application can communicate with a legacyCOM application. Now be aware that the techniques you have just learned would work for any COMserver at all. This is important to remember, given that many COM servers might never be rewrittenas native .NET applications. For example, the object model of Microsoft Outlook is currently exposedas a COM library. Thus, if you needed to build a .NET program that interacted with this product, theinteroperability layer is (currently) mandatory.

Understanding COM to .NET InteroperabilityThe next topic of this appendix is to examine the process of a COM application communicatingwith a .NET type. This “direction” of interop allows legacy COM code bases (such as an existing VB6project) to make use of functionality contained within newer .NET assemblies. As you might imag-ine, this situation is less likely to occur than .NET to COM interop; however, it is still worth exploring.

For a COM application to make use of a .NET type, we somehow need to fool the COM program into believing that the managed .NET type is in fact unmanaged. In essence, you need toallow the COM application to interact with the .NET type using the functionality required by theCOM architecture. For example, the COM type should be able to obtain new interfaces throughQueryInterface() calls, simulate unmanaged memory management using AddRef() and Release(),make use of the COM connection point protocol, and so on.

Beyond fooling the COM client, COM to .NET interoperability also involves fooling the COMruntime. A COM server is activated using the COM runtime rather than the CLR. For this to happen,the COM runtime must look up numerous bits of information in the system registry (ProgIDs,CLSIDs, IIDs, and so forth). The problem, of course, is that .NET assemblies are not registered inthe registry in the first place!

Given these points, to make your .NET assemblies available to COM clients, you must take thefollowing steps:

1. Register your .NET assembly in the system registry to allow the COM runtime to locate it.

2. Generate a COM type library (*.tlb) file (based on the .NET metadata) to allow the COMclient to interact with the public types.

3. Deploy the assembly in the same directory as the COM client or (more typically) install itinto the GAC.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1305

Page 25: Appendixes - Springer

As you will see, these steps can be performed using Visual Studio 2008 or at the command lineusing various tools that ship with the .NET Framework 3.5 SDK.

The Attributes of System.Runtime.InteropServicesIn addition to performing these steps, you will typically also need to decorate your C# types withvarious .NET attributes, all of which are defined in the System.Runtime.InteropServices name-space. These attributes ultimately control how the COM type library is created and therefore controlhow the COM application is able to interact with your managed types. Table A-4 documents some(but not all) of the attributes you can use to control the generated COM type library.

Table A-4. Select Attributes of System.Runtime.InteropServices

.NET Interop Attribute Meaning in Life

[ClassInterface] Used to create a default COM interface for a .NET class type.

[ComClass] This attribute is similar to [ClassInterface], except it also provides theability to establish the GUIDs used for the class ID (CLSID) and interfaceIDs of the COM types within the type library.

[DispId] Used to hard-code the DISPID values assigned to a member for purposesof late binding.

[Guid] Used to hard-code a GUID value in the COM type library.

[In] Exposes a member parameter as an input parameter in COM IDL.

[InterfaceType] Used to control how a .NET interface should be exposed to COM(IDispatch-only, dual, or IUnknown-only).

[Out] Exposes a member parameter as an output parameter in COM IDL.

Now do be aware that for simple COM to .NET interop scenarios, you are not required to adornyour .NET code with dozens of attributes in order to control how the underlying COM type library isdefined. However, when you need to be very specific regarding how your .NET types will be exposedto COM, the more you understand COM IDL attributes the better, given that the attributes definedin System.Runtime.InteropServices are little more than managed definitions of these IDL keywords.

The Role of the CCWBefore we walk through the steps of exposing a .NET type to COM, let’s take a look at exactly howCOM programs interact with .NET types using a COM Callable Wrapper, or CCW. As you have seen,when a .NET program communicates with a COM type, the CLR creates a Runtime Callable Wrap-per. In a similar vein, when a COM client accesses a .NET type, the CLR makes use of an interveningproxy termed the COM Callable Wrapper to negotiate the COM to .NET conversion (see Figure A-15).

Like any COM object, the CCW is a reference-counted entity. This should make sense, giventhat the COM client is assuming that the CCW is a real COM type and thus must abide by the rulesof AddRef() and Release(). When the COM client has issued the final release, the CCW releases itsreference to the real .NET type, at which point it is ready to be garbage collected.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1306

Page 26: Appendixes - Springer

Figure A-15. COM types talk to .NET types using a CCW.

The CCW implements a number of COM interfaces automatically to further the illusion thatthe proxy represents a genuine coclass. In addition to the set of custom interfaces defined by the.NET type (including an entity termed the class interface that you examine in just a moment), theCCW provides support for the standard COM behaviors described in Table A-5.

Table A-5. The CCW Supports Many Core COM Interfaces

CCW-Implemented Interface Meaning in Life

IConnectionPoint If the .NET type supports any events, they are represented as COM IConnectionPointContainer connection points.

IEnumVariant If the .NET type supports the IEnumerable interface, it appears tothe COM client as a standard COM enumerator.

IErrorInfo These interfaces allow coclasses to send COM error objects.ISupportErrorInfo

ITypeInfo These interfaces allow the COM client to pretend to manipulate an IProvideClassInfo assembly’s COM type information. In reality, the COM client is

interacting with .NET metadata.

IUnknown These core COM interfaces provide support for early and lateIDispatch binding to the .NET type.IDispatchEx

The Role of the .NET Class InterfaceIn classic COM, the only way a COM client can communicate with a COM object is to use an inter-face reference. In contrast, .NET types do not need to support any interfaces whatsoever, which isclearly a problem for a COM caller. Given that classic COM clients cannot work with object refer-ences, another responsibility of the CCW is to expose a class interface to represent each memberdefined by the type’s public sector. As you can see, the CCW is taking the same approach as VisualBasic 6.0!

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1307

Page 27: Appendixes - Springer

Defining a Class InterfaceTo define a class interface for your .NET types, you will need to apply the [ClassInterface] attrib-ute on each public class you wish to expose to COM. Again, doing so will ensure that each publicmember of the class is exposed to a default autogenerated interface that follows the same exactnaming convention as VB6 (_NameOfTheClass). Technically speaking, applying this attribute isoptional; however, you will almost always wish to do so. If you do not, the only way the COM callercan communicate with the type is using late binding (which is far less type safe and typically resultsin slower performance).

The [ClassInterface] attribute supports a named property (ClassInterfaceType) that controlsexactly how this default interface should appear in the COM type library. Table A-6 defines the pos-sible settings.

Table A-6. Values of the ClassInterfaceType Enumeration

ClassInterfaceType Member Name Meaning in Life

AutoDispatch Indicates the autogenerated default interface will onlysupport late binding, and is equivalent to not applying the[ClassInterface] attribute at all.

AutoDual Indicates that the autogenerated default interface is a “dualinterface” and can therefore be interacted with using earlybinding or late binding. This would be the same behaviortaken by VB6 when it defines a default COM interface.

None Indicates that no interface will be generated for the class.This can be helpful when you have defined your ownstrongly typed .NET interfaces that will be exposed to COM,and do not wish to have the “freebie” interface.

In the next example, you specify ClassInterfaceType.AutoDual as the class interface designa-tion. In this way, late-binding clients such as VBScript can access the Add() and Subtract() methodsusing IDispatch, while early-bound clients (such as VB6 or C++) can use the class interface (named_VbDotNetCalc).

Building Your .NET TypesTo illustrate a COM type communicating with managed code, assume you have created a simpleC# Class Library project named ComCallableDotNetServer, which defines a class namedDotNetCalc. This class will define two simple methods named Add() and Subtract(). The imple-mentation logic is trivial; however, notice the use of the [ClassInterface] attribute:

// We need this to obtain the necessary// interop attributes.using System.Runtime.InteropServices;

namespace ComCallableDotNetServer{[ClassInterface(ClassInterfaceType.AutoDual)]public class DotNetCalc{public int Add(int x, int y){ return x + y; }

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1308

Page 28: Appendixes - Springer

public int Subtract(int x, int y){ return x - y; }

}}

As mentioned earlier in this appendix, in the world of COM, just about everything is identifiedusing a 128-bit number termed a GUID. These values are recorded into the system registry in orderto define an identity of the COM type. Here, we have not specifically defined GUID values for ourDotNetCalc class, and therefore the type library exporter tool (tlbexp.exe) will generate GUIDs onthe fly. The problem with this approach, of course, is that each time you generate the type library(which we will do shortly), you receive unique GUID values, which can break existing COM clients.

To define specific GUID values, you may make use of the guidgen.exe utility, which is accessi-ble from the Tools ➤ Create Guid menu item of Visual Studio 2008. Although this tool provides fourGUID formats, the [Guid] attribute demands the GUID value be defined using the Registry Formatoption, as shown in Figure A-16.

Figure A-16. Obtaining a GUID value

Once you copy this value to your clipboard (via the Copy GUID button), you can then paste itin as an argument to the [Guid] attribute. Be aware that you must remove the curly brackets fromthe GUID value! This being said, here is our updated DotNetCalc class type (your GUID value willdiffer):

[ClassInterface(ClassInterfaceType.AutoDual)][Guid("4137CFAB-530B-4667-ADF2-8E2CD63CB462")]public class DotNetCalc{public int Add(int x, int y){ return x + y; }

public int Subtract(int x, int y){ return x - y; }

}

On a related note, click the Show All Files button on the Solution Explorer and open up theAssemblyInfo.cs file located under the Properties icon. By default, all Visual Studio 2008 projectworkspaces are provided with an assembly-level [Guid] attribute used to identify the GUID of thetype library generated based on the .NET server (if exposed to COM).

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1309

Page 29: Appendixes - Springer

// The following GUID is for the ID of the typelib if this project is exposed to COM[Assembly: Guid("EB268C4F-EB36-464C-8A25-93212C00DC89")]

Defining a Strong NameAs a best practice, all .NET assemblies that are exposed to COM should be assigned a strong nameand installed into the global assembly cache (the GAC). Technically speaking, this is not required;however, if you do not deploy the assembly to the GAC, you will need to copy this assembly into thesame folder as the COM application making use of it.

Given that Chapter 15 already walked you through the details of defining a strongly namedassembly, simply generate a new *.snk file for signing purposes using the Signing tab of the Proper-ties editor. At this point, you can compile your assembly and install ComCallableDotNetServer.dllinto the GAC using gacutil.exe (again, see Chapter 15 for details).

gacutil -i ComCallableDotNetServer.dll

Generating the Type Library and Registering the.NET TypesAt this point, we are ready to generate the necessary COM type library and register our .NET assem-bly into the system registry for use by COM. Do to so, you can take two possible approaches. Yourfirst approach is to use a command-line tool named regasm.exe, which ships with the .NET Frame-work 3.5 SDK. This tool will add several listings to the system registry, and when you specify the /tlbflag, it will also generate the required type library, as shown here:

regasm ComCallableDotNetServer.dll /tlb

■Note The .NET Framework 3.5 SDK also provides a tool named tlbexp.exe. Like regasm.exe, this tool willgenerate type libraries from a .NET assembly; however, it does not add the necessary registry entries. Given this, itis more common to simply use regasm.exe to perform each required step.

While regasm.exe provides the greatest level of flexibility regarding how the COM type library isto be generated, Visual Studio 2008 provides a handy alternative. Using the Properties editor, simplycheck the Register for COM interop option on the Compile tab, as shown in Figure A-17, and recom-pile your assembly.

Once you have run regasm.exe or enabled the Register for COM Interop option, you will findthat your bin\Debug folder now contains a COM type library file (taking a *.tlb file extension).

■Source Code ComCallableDotNetServer application is included under the Appendix A subdirectory.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1310

Page 30: Appendixes - Springer

Figure A-17. Registering an assembly for COM interop using Visual Studio 2008

Examining the Exported Type InformationNow that you have generated the corresponding COM type library, you can view its contents usingthe OLE View utility by loading the *.tlb file. If you load ComCallableDotNetServer.tlb (via the File➤ View Type Library menu option), you will find the COM type descriptions for each of your .NETclass types. For example, the DotNetCalc class has been defined to support the default _DotNetClassinterface due to the [ClassInterface] attribute, as well as an interface named (surprise, surprise)_Object. As you would guess, this is an unmanaged definition of the functionality defined bySystem.Object:

[uuid(88737214-2E55-4D1B-A354-7A538BD9AB2D),version(1.0), custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9},"ComCallableDotNetServer.DotNetCalc")]coclass DotNetCalc {[default] interface _DotNetCalc;interface _Object;

};

As specified by the [ClassInterface] attribute, the default interface has been configured as adual interface, and can therefore be accessed using early or late binding:

[odl, uuid(AC807681-8C59-39A2-AD49-3072994C1EB1), hidden,dual, nonextensible, oleautomation,custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9},"ComCallableDotNetServer.DotNetCalc")]interface _DotNetCalc : IDispatch {[id(00000000), propget,custom({54FC8F55-38DE-4703-9C4E-250351302B1C}, "1")]HRESULT ToString([out, retval] BSTR* pRetVal);[id(0x60020001)]HRESULT Equals( [in] VARIANT obj,

[out, retval] VARIANT_BOOL* pRetVal);[id(0x60020002)]HRESULT GetHashCode([out, retval] long* pRetVal);[id(0x60020003)]HRESULT GetType([out, retval] _Type** pRetVal);[id(0x60020004)]HRESULT Add([in] long x, [in] long y,

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1311

Page 31: Appendixes - Springer

[out, retval] long* pRetVal);[id(0x60020005)]HRESULT Subtract( [in] long x, [in] long y,

[out, retval] long* pRetVal);};

Notice that the _DotNetCalc interface not only describes the Add() and Subtract() methods,but also exposes the members inherited by System.Object. As a rule, when you expose a .NET classtype to COM, all public methods defined up the chain of inheritance are also exposed through theautogenerated class interface.

Building a Visual Basic 6.0 Test ClientNow that the .NET assembly has been properly configured to interact with the COM runtime, youcan build some COM clients. You can create a simple VB6 Standard *.exe project type (namedVB6DotNetClient) and set a reference to the new generated type library (see Figure A-18).

Figure A-18. Referencing your .NET server from VB6

As for the GUI front end, keep things really simple. A single Button object will be used tomanipulate the DotNetCalc .NET type. Here is the code (notice that you are also invokingToString(), defined by the _Object interface):

Private Sub btnUseDotNetObject_Click()' Create the .NET object.Dim c As New DotNetCalcMsgBox c.Add(10, 10), , "Adding with .NET"

' Invoke some members of System.Object.MsgBox c.ToString, , "ToString value"

End Sub

■Source Code The VB6DotNetClient application is included under the Appendix A subdirectory.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY1312

Page 32: Appendixes - Springer

So, at this point you have seen the process of building .NET applications that talk to COM typesand COM applications that talk to .NET types. Again, while there are many additional topics regard-ing the role of interop services, you should be in a solid position for further exploration.

Summary.NET is a wonderful thing. Nevertheless, managed and unmanaged code must learn to worktogether for some time to come. Given this fact, the .NET platform provides various techniquesthat allow you to blend the best of both worlds.

A major section of this appendix focused on the details of .NET types using legacy COM com-ponents. As you have seen, the process begins by generating an assembly proxy for your COM types.The RCW forwards calls to the underlying COM binary and takes care of the details of mappingCOM types to their .NET equivalents.

The appendix concluded by examining how COM types can call on the services of newer .NETtypes. As you have seen, this requires that the creatable types in the .NET assembly are registeredfor use by COM, and that the .NET types are described via a COM type library.

APPENDIX A ■ COM AND .NET INTEROPERABIL ITY 1313

Page 33: Appendixes - Springer

Platform-Independent .NETDevelopment with Mono

This appendix introduces you to the topic of cross-platform C# and .NET development using anopen source implementation of .NET named Mono (in case you are wondering about the name,“Mono” is a Spanish word for monkey, as in “code monkey,” a term often used to describe individu-als who author code for a living). In this appendix, you will come to understand the role of theCommon Language Infrastructure (CLI), the overall scope of Mono, and numerous Mono develop-ment tools. Given your work over the course of this text, you will be in a perfect position to digfurther into Mono development as you see fit at the conclusion of this appendix.

■Note If you require a detailed treatment of cross-platform .NET development, I recommend picking up a copy ofCross-Platform .NET Development: Using Mono, Portable .NET, and Microsoft .NET by Mark Easton and Jason King(Apress, 2004).

The Platform-Independent Nature of .NETHistorically speaking, when programmers made use of a Microsoft development language orprogramming framework (VB6, MFC, COM, ATL, etc.), they had to resign themselves to buildingsoftware that (by and large) only executed on the Windows family of operating systems. Many .NETdevelopers, accustomed to previous Microsoft development options, are quite surprised when theylearn that .NET is platform-independent. But it’s true. You can compile and execute .NET assemblieson operating systems other than Microsoft Windows.

Using open source .NET implementations such as Mono, Mac OS X, Solaris, AIX, as well asnumerous flavors of Unix/Linux can be happy homes for your .NET binaries. Furthermore, Monoprovides an installation package for (surprise, surprise) Microsoft Windows. Thus, it is possible tobuild and run .NET assemblies on the Windows operating system, without ever installing theMicrosoft .NET Framework 3.5 SDK or the Visual Studio 2008 IDE.

■Note Be aware, however, that if you are only interested in building .NET software for the Windows operatingsystem, the Microsoft .NET Framework 3.5 SDK and Visual Studio 2008 provide the best options for doing so.

Even after developers are made aware of .NET code’s cross-platform capabilities, they oftenassume that the scope of platform-independent .NET development is limited to little more than

1315

A P P E N D I X B

Page 34: Appendixes - Springer

“Hello World” console applications. In reality, however, you can build production-ready assembliesthat make use of ADO.NET, Windows Forms (in addition to alternative GUI toolkits such as GTK#and Cocoa#), ASP.NET, and XML web services using many of the core namespaces and languagefeatures you have seen used throughout this text.

The way in which .NET’s cross-platform nature is achieved is different from the approachtaking by Sun Microsystems with the handling of the Java programming platform. Unlike Java,Microsoft itself does not provide installers of .NET for Mac, Linux, etc. Rather, Microsoft hasreleased a set of formalized specifications that other entities can use as a road map for building.NET distributions for their platform(s) of choice. Collectively, these specifications are termedthe CLI.

The Role of the CLIAs briefly mentioned in Chapter 1, when C# and the .NET platform were released to the world atlarge, Microsoft Corporation submitted two formal specifications to ECMA (European ComputerManufacturers Association). Once approved, these same specifications were submitted to theInternational Organization for Standardization (ISO) and ratified shortly thereafter.

So, why on earth should you care? Again, these two specifications provide a road map forother companies, developers, universities, and other such organizations to build their own customdistributions of the C# programming language and the .NET platform. The two specifications inquestion are

• ECMA-334, which defines the syntax and semantics of the C# programming language

• ECMA-335, which defines numerous details of the .NET platform, collectively termed theCommon Language Infrastructure

ECMA-334 tackles the lexical grammar of C# in an extremely rigorous and scientific manner(as you might guess, this level of detail is quite important to those implementing their own C# com-piler). However, ECMA-335 is the meatier of the two specifications, so much so that it has beenbroken down into six partitions, as listed in Table B-1.

Table B-1. ECMA-335 Specification Partitions

ECMA-335 Partition Meaning in Life

Partition I: Architecture Describes the overall architecture of the CLI, including the rules ofthe Common Type System, the Common Language Specification,and the mechanics of the .NET runtime engine.

Partition II: Metadata Describes the details of the .NET metadata format.

Partition III: CIL Describes the syntax and semantics of the common intermediatelanguage (CIL) programming language.

Partition IV: Libraries Gives a high-level overview of the minimal and complete classlibraries that must be supported by a CLI-compatible .NETdistribution.

Partition V: Binary Formats Provides details of the portable debug interchange format(CILDB). Portable CILDB files provide a standard way tointerchange debugging information between CLI producersand consumers.

Partition VI: Annexes Represents a collection of “odds and ends” examining topics suchas class library design guidelines and the implementation detailsof a CIL compiler.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1316

Page 35: Appendixes - Springer

The point of this appendix is not to dive into the details of the ECMA-334 and ECMA-335 speci-fications—nor are you required to know the ins-and-outs of these documents to understand how tobuild platform-independent .NET assemblies. However, if you are interested, you can downloadboth of these specifications for free from the ECMA website (http://www.ecma-international.org/publications/standards).

■Note Even if you have no interest in the cross-platform aspects of .NET, I would recommend reading the ECMA-334 and ECMA-335 specifications, as they provide a number of insights regarding the C# language andthe .NET platform.

The Mainstream CLI DistributionsTo date, there are two mainstream implementations of the CLI, beyond Microsoft’s CLR, MicrosoftSilverlight, and the Microsoft NET Compact Framework (see Table B-2).

Table B-2. Mainstream .NET CLI Distributions

CLI Distribution Supporting Website Meaning in Life

Mono http://www.mono-project.com Mono is an open source and commerciallysupported distribution of .NET sponsoredby Novell Corporation.Mono is targeted to run on many popularflavors of Unix/Linux, Mac OS X, Solaris,and Windows.

Portable .NET http://www.dotgnu.org Portable .NET is distributed under the GNUGeneral Public License.As the name implies, Portable .NET intendsto function on as many operation systemsand architectures as possible, includingmany esoteric platforms such as BeOS,Microsoft Xbox, and Sony PlayStation (no,I’m not kidding about those last two!).

Each of the CLI implementations shown in Table B-2 provide a fully function C# compiler,numerous command-line development tools, a global assembly cache (GAC) implementation, sam-ple code, useful documentation, and dozens of assemblies that constitute the base class libraries.

Beyond implementing the core libraries defined by Partition IV of ECMA-335, Mono andPortable .NET provide Microsoft-compatible implementations of mscorlib.dll, System.Data.dll,System.Web.dll, System.Drawing.dll, and System.Windows.Forms.dll (among many others).Furthermore, the Mono and Portable .NET distribution also ship with a handful of assembliesspecifically targeted at Unix/Linux and Mac OS X operating systems. For example, Cocoa# is a.NET wrapper around the Mac OX GUI toolkit, Cocoa. In this appendix, I will not dig into these OS-specific binaries and instead stay focused on making use of the OS-agonistic programming stacks.

■Note Portable .NET will not be examined in this appendix. However, it is important to know that Mono is not theonly platform-independent distribution of the .NET platform available today. I would recommend you take sometime to play around with Portable .NET in addition to the Mono platform.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1317

Page 36: Appendixes - Springer

The Scope of MonoGiven that Mono is an API built on existing ECMA specifications that originated from MicrosoftCorporation, you would be correct in assuming that Mono is playing a constant game of catch up asnewer versions of Microsoft’s .NET platform are released. At the time of this writing, Mono is com-patible with C# 2.0/.NET 2.0. Therefore, you are able to build ASP.NET websites, Windows Formsapplications, database-centric applications using ADO.NET, and (of course) simple consoleapplications.

Currently, Mono is not completely compatible with C# 2008 or .NET 3.0/3.5. What that means isyour Mono applications are currently unable (again, at the time of this writing) to make use of thefollowing APIs:

• Windows Presentation Foundation (WPF)

• Windows Communication Foundation (WCF)

• Windows Workflow Foundation (WF)

• The LINQ APIs

• C# 2008–specific language features

Rest assured that the Novell-based Mono team is already working on incorporating these APIsand C# 2008 programming features into the Mono project. In fact, many C# 2008 language featuresare already part of the latest build of Mono (1.2.5), including implicit typing, object initializationsyntax, and anonymous types.

■Note The C# 2008 support is enabled by passing the -langversion:linq option to the Mono C# compiler.

In addition, the Olive project, which plans to bring WPF, WCF, and WF into the Mono platform,is currently underway. LINQ support, you will be happy to know, is also moving along nicely.

■Note The Mono website maintains a page that describes the overall road map of Mono’s functionality and plansfor future releases (http://www.mono-project.com/plans).

The final point of interest regarding the Mono feature set is that much like Microsoft’s .NETFramework 3.5 SDK, the Mono SDK supports a number of .NET programming languages. While thisappendix will stay focused on C#, Mono does provide support for a Visual Basic .NET–compatiblecompiler, as well as support for many other .NET-aware programming languages.

Obtaining and Installing MonoWith this basic primer behind us, we can turn our attention to obtaining and installing Mono onyour operating system of choice. Navigate to the Mono website (http://www.mono-project.com) andclick the Download Now button to navigate to the downloads page. Here you are able to download avariety of installers.

I am assuming that you are installing the Windows distribution of Mono (note that installingMono will not interfere whatsoever with any existing installation of Microsoft .NET or Visual StudioIDEs). Begin by downloading the current stable Mono installation package for Microsoft Windowsand saving the setup program to your local hard drive.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1318

Page 37: Appendixes - Springer

■Note If you are installing Mono on a Linux-based OS, I’d suggest doing so using the Linux Installer for x86package, which will allow you to install Mono using a friendly setup wizard (rather than forcing you to install Monofrom source; be sure to read the supplied installation notes on the Mono website). If you make use of the Mac OS XMono installer, the installation process will be identical to installing other Mac-based software.

When you run the setup program, you will be given a chance to install a variety of Mono devel-opment tools beyond the expected base class libraries and the C# programming tools. Specifically,the installer will ask you whether you wish to include GTK# (an open source .NET GUI API basedon the Linux-centric GTK toolkit) and XSP (a stand-alone web server, similar to Microsoft’s webdev.webserver.exe). In this appendix, I will assume you have opted for a full installation, so be sure youhave checked each option in the setup script (see Figure B-1).

Figure B-1. Select all options for your Mono installation.

All of the remaining options of the Mono installer can be left using the suggested default values.

Examining Mono’s Directory StructureBy default, Mono installs under C:\Program Files\Mono-<version> (at the time of this writing, thelatest and greatest version of Mono is 1.2.5). Beneath that root you will find a number of subdirecto-ries (see Figure B-2).

For this appendix, you need only concern yourself with the following subdirectories:

• bin: Contains a majority of the Mono development tools including the C# command-linecompilers

• lib\mono\gac: The location of Mono’s global assembly cache

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1319

Page 38: Appendixes - Springer

Figure B-2. The Mono directory structure

Given that you run the vast majority of the Mono development tools from the command line,you will want to make use of the Mono command prompt, which automatically recognizes each ofthe command-line development tools. The command prompt (which is functionally equivalent tothe Visual Studio 2008 command prompt) can be activated by selecting Start ➤ All Programs ➤Mono <version> For Windows menu option. To test your installation, enter the following commandand press the Enter key:

mono --version

If all is well, you should see various details regarding the Mono runtime environment (see Figure B-3).

Figure B-3. The Mono runtime environment

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1320

Page 39: Appendixes - Springer

The Mono Development ToolsSimilar to the Microsoft’s CLR distribution, Mono ships with a number of managed compilers:

• mcs/gmcs: The C# compilers

• vbnc: The Mono Visual Basic compiler

• booc: The Boo language compiler

• ilasm/ilasm2: The Mono CIL compilers

While this appendix focuses only on the C# compilers, again recall that the Mono project doesship with a Visual Basic .NET compiler. While this tool is currently under development, the intendedgoal is to bring the world of human-readable keywords (Inherits, MustOverride, Implements, etc.) tothe world of Unix/Linux and Mac OS X (see http://www.mono-project.com/Visual_Basic for moredetail).

Boo is an object-oriented statically typed programming language for the CLI that sports aPython-based syntax. Check out http://boo.codehaus.org for more details on the Boo program-ming language. Finally, as you might have guessed, ilasm/ilasm2 are the Mono CIL compilers (thesecond of which supports .NET 2.0 programming constructs).

Working with the C# CompilersThe first C# compiler for the Mono project was mcs, and it’s fully compatible with C# 1.1 (in fact, mcsis written in C#). Like the Microsoft C# command-line compiler (csc.exe), mcs supports responsefiles, a /target: flag (to define the assembly type), an /out: flag (to define the name of the compiledassembly), and a /reference: flag (to update the manifest of the current assembly with externaldependencies). You can view all the options of mcs using the following command:

mcs -?

The “generic mono C# compiler,” or gmcs, as the name implies, is a version of mcs that has sup-port for .NET 2.0–specific C# language features (generics, covariance/contravariance, nullabletypes, partial types, anonymous methods, etc.) and references the .NET 2.0–based base classlibraries. The command-line options of gmcs are identical to mcs, which you can verify with thefollowing command:

gmcs -?

Given the presence of two C# compilers, you might naturally assume that only gmcs can beused to build .NET applications that make use of the C# 2.0 language enhancements. In reality, mcswas the first of the two compilers to support 2.0 features, which were perfected and ported to gmcs.The code examples in this appendix can be compiled using either of the two C# compilers, so pickyour poison.

Microsoft-Compatible Mono Development ToolsIn addition to various managed compilers, Mono ships with various development tools that arefunctionally equivalent to tools found in the Microsoft .NET SDK (some of which are identicallynamed). Table B-3 enumerates the mappings between some of the commonly usedMono/Microsoft .NET utilities.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1321

Page 40: Appendixes - Springer

Table B-3. Mono Command-Line Tools and Their Microsoft .NET Counterparts

Mono Utility Microsoft .NET Utility Meaning in Life

al al.exe Manipulates assembly manifests and buildsmultifile assemblies (among other things)

gacutil gacutil.exe Interacts with the GAC

mono when run with ngen.exe Performs a precompilation of an assembly’s the -aot option CIL code

wsdl wsdl.exe Generates client-side proxy code for XML webservices

disco disco.exe Discovers the URLs of XML web serviceslocated on a web server

xsd xsd.exe Generates type definitions from an XSDschema file

sn sn.exe Generates key data for a strongly namedassembly

monodis ildasm.exe The CIL disassembler

ilasm ilasm.exe The CIL assembler

xsp2 webdev.webserver.exe A testing and development ASP.NET webserver

Mono-Specific Development ToolsIn addition, there are Mono development tools for which no direct Microsoft .NET Framework 3.5SDK equivalents exist, and these are listed in Table B-4.

Table B-4. Mono Tools That Have No Direct Microsoft .NET SDK Equivalent

Mono-Specific Development Tool Meaning in Life

monop/monop2 The monop (mono print) utility will display the definition of aspecified type in the syntax of C#.

SQL# The Mono Project ships with a graphical front end (SQL#) toallow you to interact with relational databases using a varietyof ADO.NET data providers.

Glade 3 This tool is a visual development IDE for building GTK#graphical applications.

■Note You can load SQL# and Glade by using Windows’s Start button and navigating to the Applications folderwithin the Mono installation directory. Be sure to do so, as it will clearly illustrate how rich the Mono platform hasbecome.

Using monop(2)The monop and monop2 utilities (both of which are shorthand for mono print) can be used to displaythe C# definition of a given type within a specified assembly. The distinction between these two

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1322

Page 41: Appendixes - Springer

utilities is that monop is programmed to only display types compatible with Microsoft .NET 1.1,whereas monop2 will also display types compatible with Microsoft .NET 2.0. As you might suspect,these tools can be quite helpful when you wish to quickly view a method signature, rather than dig-ging through the formal documentation. By way of a quick test, enter the following commandwithin a Mono command prompt:

monop2 System.Object

Figure B-4 shows the definition of our good friend System.Object.

Figure B-4. monop(2) displays C# code definitions for compiled types.

You’ll see the use of additional Mono tools over the course of this appendix; however, you maywish to specify -? as an argument to a tool of interest to see the available command set.

Building .NET Applications with MonoTo illustrate Mono in action, you will begin by building a code library named CoreLibDumper.dll.This assembly contains a single class type named CoreLibDumper that supports a static methodnamed DumpTypeToFile(). The method takes a string parameter that represents the fully qualifiedname of any type within mscorlib.dll and obtains the related type information via the reflectionAPI (see Chapter 16), dumping the class member signatures to a local file on the hard drive.

Building a Mono Code LibraryCreate a new folder on your C drive named MonoCode. Within this new folder, create a subfoldernamed CoreLibDumper that contains the following C# file (named CorLibDumper.cs):

// CoreLibDumper.csusing System;using System.Reflection;using System.IO;

// Define assembly version.[assembly:AssemblyVersion("1.0.0.0")]

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1323

Page 42: Appendixes - Springer

namespace CoreLibDumper{public class TypeDumper{public static bool DumpTypeToFile(string typeToDisplay){// Attempt to load type into memory.Type theType = null;try{

// Throw exception if we can't find it.theType = Type.GetType(typeToDisplay, true);

} catch { return false; }

// Create local *.txt file.using(StreamWriter sw =

File.CreateText(string.Format("{0}.txt",theType.FullName)))

{// Now dump type to file.sw.WriteLine("Type Name: {0}", theType.FullName);sw.WriteLine("Members:");foreach(MemberInfo mi in theType.GetMembers())sw.WriteLine("\t-> {0}", mi.ToString());

}return true;

}}

}

Like the Microsoft C# compiler, the Mono C# compilers support the use of response files (seeChapter 2). While you could compile this file by specifying each required argument manually atthe command line, instead create a new file named LibraryBuild.rsp (in the same location asCoreLibDumper.cs) that contains the following command set:

/target:library/out:CoreLibDumper.dllCoreLibDumper.cs

You can now compile your library at the command line as follows:

gmcs @LibraryBuild.rsp

This approach is functionally equivalent to the following (more verbose) command set:

gmcs /target:library /out:CoreLibDumper.dll CoreLibDumper.cs

Assigning CoreLibDumper.dll a Strong NameMono supports the notion of deploying strongly named and shared assemblies (see Chapter 15) tothe Mono GAC. To generate the necessary public/private key data, Mono provides the sn command-line utility, which functions more or less identically to Microsoft’s tool of the same name. Forexample, the following command generates a new *.snk file (specify the -? option to view allpossible commands):

sn -k myTestKeyPair.snk

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1324

Page 43: Appendixes - Springer

To inform the C# compiler to make use of this key data to assign a strong name toCoreLibDumper.dll, simply update your LibraryBuild.rsp file with the following additionalcommand:

/target:library/out:CoreLibDumper.dll/keyfile:myTestKeyPair.snkCoreLibDumper.cs

Now recompile your assembly:

gmcs @LibraryBuild.rsp

Viewing the Updated Manifest with monodisBefore deploying the assembly to the Mono GAC, allow me to introduce the monodis command-linetool, which is the functional equivalent of Microsoft’s ildasm.exe (without the GUI front end). Usingmonodis, you can view the CIL code, manifest, and type metadata for a specified assembly. In thiscase, we’re interested in viewing the core details of our (now strongly named) assembly via the --assembly flag. Figure B-5 shows the result of the following command set:

monodis --assembly CoreLibDumper.dll

Figure B-5. monodis allows you to view the CIL code, metadata, and manifest of an assembly.

As you can see, the assembly’s manifest now exposes the public key value defined withinmyTestKeyPair.snk.

Installing Assemblies into the Mono GACNow that you have provided CoreLibDumper.dll with a strong name, you install it into the MonoGAC using gacutil. Like Microsoft’s tool of the same name, Mono’s gacutil supports options toinstall, uninstall, and list the current assemblies installed under C:\Program Files\Mono-<version>\lib\mono\gac. The following command deploys CoreLibDumper.dll to the GAC and sets it up as ashared assembly on the machine.

gacutil -i CoreLibDumper.dll

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1325

Page 44: Appendixes - Springer

■Note Be sure to use a Mono command prompt to install this binary to the Mono GAC! If you use the Microsoftgacutil.exe program, you’ll install CoreLibDumper.dll into the Microsoft GAC!

After running the command, if you open the \gac directory, you should find a new foldernamed CoreLibDumper (see Figure B-6), which defines a subdirectory that follows the same namingconventions as Microsoft’s GAC (versionOfAssembly__publicKeyToken).

Figure B-6. Deploying our code library to the Mono GAC

■Note Supplying the -l option to gacutil will list out each assembly in the Mono GAC.

Building a Console Application in MonoYour first Mono client will be a simple console-based application named ConsoleClientApp.exe.Create a new file in your C:\MonoCode\CorLibDumper folder, ConsoleClientApp.cs, that containsthe following Program type:

// This client app makes use of the CoreLibDumper.dll// to dump types to a file.using System;using CoreLibDumper;

namespace ConsoleClientApp{public class Program{public static void Main(){Console.WriteLine(

"***** The Type Dumper App *****\n");

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1326

Page 45: Appendixes - Springer

// Ask user for name of type.string typeName = "";Console.Write("Please enter type name: ");typeName = Console.ReadLine();

// Now send it to the helper library.if(TypeDumper.DumpTypeToFile(typeName))

Console.WriteLine("Data saved into {0}.txt",typeName);

elseConsole.WriteLine("Error! Can't find that type...");

}}

}

Notice that the Main() method simply prompts the user for a fully qualified type name. TheTypeDumper.DumpTypeToFile() method uses the user-entered name to dump the type’s membersto a local file. Next, create a ClientBuild.rsp file for this client application that referencesCoreLibDumper.dll:

/target:exe/out:ConsoleClientApp.exe/reference:CoreLibDumper.dllConsoleClientApp.cs

Now, using a Mono command prompt, change to the folder containing your client files andcompile the executable using gmcs as shown here:

gmcs @ClientBuild.rsp

Loading Our Client Application in the Mono RuntimeAt this point, you can load ConsoleClientApp.exe into the Mono runtime engine by specifying thename of the executable (with the *.exe file extension) as an argument to mono:

mono ConsoleClientApp.exe

As a test, enter System.Threading.Thread at the prompt, and press the Enter key. You will nowfind a new file named System.Threading.Thread.txt containing the type’s metadata definition (seeFigure B-7).

Before moving on to a Windows Forms–based client, try the following experiment. Using theWindows Explorer, rename the CoreLibDumper.dll assembly from the folder containing the clientapplication to DontUseCoreLibDumper.dll. You should be able to still successfully run the clientapplication, as the only reason we needed access to this assembly when building the client was toupdate the client manifest. At runtime, the Mono runtime will load the version ofCoreLibDumper.dll you deployed to the Mono GAC.

However, if you open Windows Explorer and attempt to run your client application by double-clicking ConsoleClientApp.exe, you might be surprised to find a FileNotFoundException is thrown.At first glance, you might assume this is due to the fact that you renamed CoreLibDumper.dll fromthe location of the client application. However, the true reason is because you just loadedConsoleClientApp.exe into the Microsoft CLR!

To run an application under Mono, you must pass it into the Mono runtime via mono. If you donot, you will be loading your assembly into the Microsoft CLR, which assumes all shared assembliesare installed into the Microsoft GAC located in the <%windir%>\Assembly directory.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1327

Page 46: Appendixes - Springer

Figure B-7. Result of running our client application

Building a Windows Forms Client ProgramBefore continuing, be sure to rename DontUseCoreLibDumper.dll back to CoreLibDumper.dll. Next,create a new C# file named WinFormsClientApp.cs saved in the same location as your current proj-ect files. This file defines two types, both of which make use of a few C# 2.0 language features,including static classes and anonymous methods:

using System;using System.Windows.Forms;using CoreLibDumper;using System.Drawing;

namespace WinFormsClientApp{// Application object.public static class Program{public static void Main(){Application.Run(new MainWindow());

}}

// Our simple Window.public class MainWindow : Form{private Button btnDumpToFile = new Button();private TextBox txtTypeName = new TextBox();

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1328

Page 47: Appendixes - Springer

public MainWindow(){// Config the UI.ConfigControls();

}

private void ConfigControls(){// Configure the Form.Text = "My Mono Win Forms App!";ClientSize = new System.Drawing.Size(366, 90);StartPosition = FormStartPosition.CenterScreen;AcceptButton = btnDumpToFile;

// Configure the Button.btnDumpToFile.Text = "Dump";btnDumpToFile.Location = new System.Drawing.Point(13, 40);

// Handle click event anonymously.btnDumpToFile.Click += delegate{if(TypeDumper.DumpTypeToFile(txtTypeName.Text))MessageBox.Show(string.Format("Data saved into {0}.txt",txtTypeName.Text));

elseMessageBox.Show("Error! Can't find that type...");

};Controls.Add(btnDumpToFile);

// Configure the TextBox.txtTypeName.Location = new System.Drawing.Point(13, 13);txtTypeName.Size = new System.Drawing.Size(341, 20);Controls.Add(txtTypeName);

}}

}

To compile this Windows Forms application using a response file, create a file namedWinFormsClientApp.rsp (the contents of which follow) and supply that as an argument to gmcsas shown previously.

/target:winexe/out:WinFormsClientApp.exe/r:CoreLibDumper.dll/r:System.Windows.Forms.dll/r:System.Drawing.dllWinFormsClientApp.cs

Finally, run your Windows Forms application via mono:

mono WinFormsClientApp.exe

Figure B-8 shows the output.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1329

Page 48: Appendixes - Springer

Figure B-8. A Windows Forms application build using Mono

Executing Our Windows Forms Application Under LinuxUp until now, this appendix has created a few assemblies that could have been compiled using theMicrosoft .NET Framework 3.5 SDK. However, the importance of Mono becomes quite clear whenyou view Figure B-9, which shows the same exact Windows Forms application running under SuSeLinux. Notice how our Windows Forms application has taken on the correct look and feel of mycurrent theme.

Figure B-9. Our Windows Forms application executing under SuSe Linux!

■Source Code The CorLibDumper project can be found under the Appendix B subdirectory.

So, you can compile and execute the same exact C# code shown during this appendix on Linux(or any OS supported by Mono) using the same Mono development tools. In fact, you can deploy orrecompile any of the assemblies created in this text that do not use 3.0 or 3.5 programming con-structs to a new Mono-aware OS and run them directly using the mono runtime utility. Because allassemblies simply contain platform-agonistic CIL code, you are not required to recompile theapplications whatsoever.

■Note Do recall that Mono 1.2.5 does have limited support for C# 2008 language features, so some of theexamples from Chapter 13 should work as-is.

Suggestions for Further StudyIf you followed along with the materials presented in this book, you already know a great deal aboutMono, given that it is an ECMA-compatible implementation of the CLI. If you are interested inlearning more about Mono particulars, the first place to begin is the official Mono website (http://www.mono-project.com). Specifically, you should be sure to examine http://www.mono-project.com/Use, as this page is an entry point to a number of important topics including database access usingADO.NET, web development using ASP.NET, and so forth.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1330

Page 49: Appendixes - Springer

As well, I have authored some Mono-centric articles on the DevX website (http://www.devx.com) that may be of interest to you:

• “Mono IDEs: Going Beyond the Command Line”: Examines numerous Mono-aware IDEs

• “Building Robust UIs in Mono with Gtk#”: Examines building desktop applications using theGTK# toolkit as an alternative to Windows Forms

Last but not least, be aware of the Mono documentation website (http://www.go-mono.com/docs). Here you will find documentation on the Mono base class libraries, development tools, andother topics (see Figure B-10).

Figure B-10. The online Mono documentation

■Note Mono’s online documentation website is community supported; therefore, don’t be too surprised if youfind some incomplete documentation links! Given that Mono is an ECMA-compatible distribution of Microsoft .NET,you may prefer to make use of the feature-rich MSDN online documentation when exploring Mono.

SummaryThe point of this appendix was to provide an introduction to the cross-platform nature of the C#programming language and the .NET platform using the Mono framework. As you have seen, Monoships with a number of command-line tools that allow you to build any variety of .NET assembly,including strongly named assemblies deployed to the GAC, Windows Forms applications, and .NETcode libraries.

As explained, Mono is not fully compatible with the .NET 3.0 or .NET 3.5 programming APIs(WPF, WCF, WF, or LINQ) or the C# 2008 language features (however, Mono 1.2.5 has some limited

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO 1331

Page 50: Appendixes - Springer

C# 2008 language support). Efforts are underway (via the Olive project) to bring these aspects of theMicrosoft .NET platform to Mono. In any case, if you need to build .NET applications that can exe-cute under a variety of operating systems, the Mono project is a wonderful choice to do so.

APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO1332

Page 51: Appendixes - Springer

Special Characters<%@ XXX %> markers, 1183<%@Master%> directive, 1217<%@Page%> directive attribute, ASP.NET, 1184<%= .%> notation, 1176<%Import%> directive, ASP.NET, 1184–1185& operator, pointer types, 407&& operator, 103\" character, 89\\ character, 89\' character, 89? argument, 1323? operator, 107?? operator, 107|| operator, 103+ operator, 392!= operator, 102< operator, 102<= operator, 102== operator, 102> operator, 102>= operator, 102* operator, pointer types, 407

Numbers3D rendered animation, 1000100% code approach, 918

A\a character, 89Abort( ) method, Thread type, 595abstract classes, 203–204, 208, 270abstract members, 162, 204, 269, 272abstract methods, 204–208AccelerationRatio property, 1138AcceptButton property, 971, 981AcceptChanges( ) method, 785AcceptReturn property, 1081access modifiers, 163–164accessor method, 164action attribute, 1169, 1174, 1195Action property, 887Activate( ) method, 972Activated event, 972Active Template Library (ATL), description, 5ActiveX *.dll project, 1284<Ad> element, 1221Add( ) method, 95, 109, 113, 432, 864, 1077, 1259,

1286, 1288, 1298Add Reference dialog box, 489, 492, 715, 1301

Add Service Reference option, 872, 897, 908Add Web Reference button, 908AddAfterThis( )/AddBeforeThis( ) method, 864AddCacheDependency( ) method, 1199AddFirst( ) method, 864adding and removing controls, ASP.NET, 1212AddNewCarDialog property, 1114AddParams object, 615AddRef( ) method, 1291, 1305–1306address attribute, 891address element, 889AddServiceEndpoint( ) method, 892, 905ADO.NET

additional namespaces, 736vs. ADO classic, 731application configuration files, 742–743asynchronous data access, 775, 777Command object, 759–760connected layer, 755–756connected vs. disconnected layer, 733connection objects, 756–758ConnectionStringBuilder object, 758–759connectionStrings element, application

configuration, 754–755data provider definition, 733data providers overview, 733, 735DbDataReader object, 760–761definition, 731deleting records, 765example, data provider factory, 751, 753–754example database, 744Firebird Interbase data provider, 736IBM DB2 Universal Database data providers,

736IDbCommand interface, 738–739IDbConnection interface, 737IDbDataAdapter, IDataAdapter interface, 739IDbDataParameter, IDataParameter interface,

739IDbDataReader, IDataReader interface, 740IDbTransaction interface, 738inserting records, 764Microsoft data providers, 735modifying tables, Command object, 763, 771multiple result sets, DbDataReader object, 762MySQL data providers, 736overview, 731parameterized command objects, 766–767PostgreSQL providers, 736provider factory model, 749–751

Index

1333

Page 52: Appendixes - Springer

specifying DbParameter parameters, 767–768stored procedures using DbCommand, 768System.Data, 737third-party data providers, 736updating records, 765using interfaces, 741–742

AdRotator control, 1218, 1221AdRotator example, ASP.NET, 1221–1222AdRotator widget, 1221AdvertisementFile property, 1221aggregation, 196agnostic manner, 870al utility, 1322alert( ) method, 1173AllKeys member, HttpApplicationState type, 1255allocating objects with New keyword, 143–144allowAnonymous attribute, Profile Data, 1274AllowDBNull property, 787Alt property, 977Angle property, 1136, 1144AngleX property, 1136AngleY property, 1136AnimatedButtonWithDiscreteKeyFrames.xaml file,

1143AnimationInXaml.xaml file, 1142AnimationUsingKeyFrames suffix, 1142Annexes, 1316anonymous methods, 370–371anonymous profiles, 1277anonymous types, 441, 443–444App_Browsers, ASP.NET 2.0 subdirectories, 1190App_Browsers subfolder, ASP.NET 2.0, 1190App_Code subfolder, ASP.NET 2.0, 1190–1191App_Data subfolder, ASP.NET 2.0, 1190App_GlobalResources subfolder, ASP.NET 2.0, 1190App_LocalResources subfolder, ASP.NET 2.0, 1190App_Themes subfolder, ASP.NET 2.0, 1190App_WebReferences subfolder, ASP.NET 2.0, 1190App.config file, 822, 834, 854, 877, 897, 901, 1189AppDomains

advantages, 571–572creation example code, 574loading example code, 575manipulation example code, 573–574overview, 561relationship to processes, 571–572unloading example code, 576–577

AppendText( ) method, FileInfo class, System.IO,669, 672

AppExit( ) method, 1012application cache, 1245, 1259Application class, 1006application configuration files, ADO.NET, 742–743application development

cordbg.exe debugger, 35csc.exe compiler, 35–37installing .NET 3.5 Framework SDK, 35notepad.exe development editor, 35

overview, 35SharpDevelop, 35TextPad development editor, 42using Notepad, 46–47using SharpDevelop, 48–50Visual C# 2005 Express, 35

Application directory, 689application domain, garbage collection, 256application level state data, ASP.NET, 1255application object, 69–70Application property, 1195, 1253, 1256application root categories, 249–250application shutdown, ASP.NET, 1258Application type, 965

application data and processing command-linearguments, 1015–1016

Windows collection, 1016Application_End( ) event handler, 1252Application_End( ) method, HttpApplication-

derived type, 1258Application_Error( ) event handler, 1253Application_Start( ) event handler, 1252, 1256,

1259ApplicationCommands object, 1100ApplicationCommands.Help option, 1101Application.Current property, 1014Application.Current.Shutdown( ) method, 1095<ApplicationDefinition> element, 1024Application-derived class, 1013Application.Exit( ) method, 960, 979, 991Application.LoadComponent( ) method,

1026–1027ApplicationPath member, HttpRequest Type, 1196Application.Run( ) method, 957, 965, 972applications vs. sessions, ASP.NET, 1254appSetting element, Web.config, ASP.NET, 1204<appSettings> element, 1204, 1206AppStartUp( ) method, 1012array manipulation, multidimensional arrays, 119Array object, 471Array type, 460, 471ArrayList class, 305ArrayList System.Collections class type, 312–313ArrayOfObjects( ) method, 116arrays, using interface types in, 281as keyword, 211, 277ascending operator, 463, 469AsEnumerable( ) method, 840–841AskForBonus( ) method, 122*.asmx file, 908<asp:> tag, 1181</asp> tag, 1186<asp:content> scope, 1222–1223</asp:ContentPlaceHolder> tag, 1217<asp:ContentPlaceHolder> tag, 1217, 1222ASP.NET

<%@Page%> directive, 1184<%Import%> directive, 1184–1185

■INDEX1334

Page 53: Appendixes - Springer

adding and removing controls, 1212AdRotator example, 1221–1222AutoEventWireUp attribute, 1201–1202AutoPostBack property, 1208–1209browser statistics in HTTP Request processing,

1196categories of web controls, 1215classic ASP, 1175, 1177client-side scripting, 1172–1174code-behind, description, 1179code-behind page model, 1186–1188compilation cycle, 1192–1193data-centric single-file test page

adding data access logic, 1182–1183designing the UI, 1181–1182manually referencing AutoLotDAL.dll, 1180overview, 1180role of ASP.NET directives, 1183–1185

debugging and tracing, 1188default.aspx content page example, 1222–1224detailed content page example, 1228–1230Document Object Model (DOM), 1172–1173Emitting HTML, 1199enumerating controls with Panel control, 1210Error event, 1202feature-rich website example

defining default.aspx content page,1222–1224

designing inventory content page, 1224–1228detailed content page, 1228–1230overview, 1215working with master pages, 1216–1222

form control declarations, 1185GET and POST, 1174–1175HTML document structure, 1168HTML form development, 1169HTML overview, 1167HTML web controls, 1214HTTP overview, 1163–1164HTTP Request members, 1196HTTP Request processing, 1195–1198HTTP Response members, 1198HTTP Response processing, 1198–1200IIS virtual directories, 1165incoming form data, 1197–1198inheritance chain, page type, 1194in-place editing example, 1227–1228Internet Information Server (IIS), description,

1164inventory content page example, 1224–1228IsPostBack property in HTTP Request

processing, 1198life cycle of a web page, 1200–1203major categories of web controls, 1213master pages example, 1216–1222.NET 3.5 web enhancements, 1178overview, 1163page type inheritance chain, 1194

positioning controls using HTML tables, 1243redirecting users, 1200referencing assemblies, 1190–1191referencing AutoLotDAL.dll assembly, 1187request/response cycle, HTTP, 1163round-trips (postbacks), 1172script block, 1185server-side event handling, 1208simple web controls, 1213simple website example, 1222single file code model, 1179sorting and paging example, 1227stateless, description, 1164submitting form data, 1174–1175System.Web.UI.Control, 1209–1210, 1212System.Web.UI.Page, 1194System.Web.UI.WebControls namespace,

1207–1209System.Web.UI.WebControls.WebControl, 1213themes

* .skin files, 1238–1239applying at page level, 1240applying sitewide, 1239–1240assigning programmatically, 1241–1242overview, 1237SkinID Property, 1240

updating code file, 1188user interface in HTML, 1170–1171using web controls, 1207–1209validating form data, 1174validation controls, 1231–1235web application, description, 1164web development server, 1166–1167web page code model, 1179, 1181web server, description, 1164WebControl base class properties, 1213website directory structure, 1190Windows XP Home Edition, 1166–1167

ASP.NET 2.0namespaces, 1179subdirectories, 1190–1191

ASP.NET profile APIaccessing profile data programmatically, 1274,

1276–1277ASPNETDB database, 1272–1273defining user profile within web.config,

1273–1274grouping profile data and persisting custom

objects, 1277–1279overview, 1272

ASP.NET website administration utility, 1205–1206aspnet_regsql.exe command-line utility, 1272aspnet_state.exe process, 1270aspnet_wp.exe process, 1270<asp:TextBox> tag, 1207*.aspx file, 1179, 1183, 1194, 1207, 1245, 1248, 1250aspx suffix, 1192

■INDEX 1335

Finditfasterathttp://superindex.apress.com

/

Page 54: Appendixes - Springer

assembliesAdd Reference dialog box, 489, 492app.config file, 502binary code reuse, 475, 481CIL code, 484, 491client application example, 492CLR file header, 483–484code base config file element, 519–520code library, 481compared with legacy executables, 480consuming shared assemblies, 510–511cross-language inheritance, 495definition, 480dependentAssembly config file element,

514–515download cache, 485dynamic redirection to a specific version,

514–515embedded resources, 484example of version updating, 512–515explicit load request, 499–500global assembly cache (GAC), 28, 482ildasm exploration of manifest, 490implicit load request, 499–500internal format, 482language integration, 494–495, 498manifest, 12, 481, 484metadata description, 12module-level manifest, 497modules, 12, 484multifile, 484–485, 496–498.NET Framework Configuration utility, 502–504,

515netmodule file extension, 485, 496–497overview, 11, 475private, 499–500probing process, 499–500publisher policy assemblies, 518–519referencing external, 28satellite assemblies, 484self-describing, 481shared assemblies, 504, 511

configuration, 512and the GAC, 509

single-file, 12, 484, 486, 488–489strong name code example, 507strong names, 481, 490, 505–508type metadata, 481, 484, 491updating applications using shared assemblies,

512version number, 481Visual Studio 2008 configuration, 502Win32 file header, 482Windows Presentation Foundation (WPF)

Application class, 1006overview, 1005Window class, 1006–1010

<assemblies> element, 1191

Assembly class, System.Reflection, 528, 536–539assembly directive, common intermediate

language (CIL), 630AssemblyBuilder, System.Reflection.Emit

namespace, 649AssemblyCompanyAttribute attribute, 550AssemblyCopyrightAttribute attribute, 550AssemblyCultureAttribute attribute, 550AssemblyDescriptionAttribute attribute, 550AssemblyInfo.cs file, 549, 1309AssemblyKeyFileAttribute attribute, 550AssemblyLoad event, System.AppDomain, 573Assembly.Load( ) method, 1191Assembly.LoadFrom( ) method, 537, 687, 690AssemblyName class, System.Reflection

namespace, 528assembly/namespace/type distinction, 23–24AssemblyOperatingSystemAttribute attribute, 550AssemblyProcessorAttribute attribute, 550AssemblyProductAttribute attribute, 550AssemblyRef, 526AssemblyResolve event, System.AppDomain, 573AssemblyTrademarkAttribute attribute, 550AssemblyVersionAttribute attribute, 550[Association] attribute, 851AsyncCallback delegate, 909AsyncCallback delegate, multithreaded

applications, 591–592asynchronous data access, ADO.NET, 775, 777asynchronous delegate call, 342–344asynchronous I/O, 685–686asynchronous multithreading using delegates,

342–344AsyncPattern property, 887AsyncResult class, multithreaded applications, 592attribute-based programming

assembly, module level attributes, 549AttributeUsage attribute, 548–549C# attribute notation, 546CLSCompliant attribute, 543COM vs. .NET attributes, 542constructor parameters, 545custom attributes, 546description, 542DllImport attribute, 543early binding, 550–551example of custom attributes, 547–548extensibility, 553–558late binding, 551–553multiple attributes, 544–545NonSerialized attribute, 543Obsolete attribute, 543, 545–546overview, 523restricting attributes, 548–549Serializable attribute, 543serializing example, 544summary of attribute key points, 546Visual Basic snap-in example, 555

■INDEX1336

Page 55: Appendixes - Springer

WebMethod attribute, 543Windows forms example, 556–557

attributes, assembly, module level, 550Attributes property, FileSystemInfo class, 663AttributeUsage attribute, 548–549authentication element, Web.config, 1204authorization element, Web.config, 1204Authorization property, 892AutoDispatch value, ClassInterfaceType

enumeration, 1308AutoDual value, ClassInterfaceType enumeration,

1308AutoEventWireUp attribute, ASP.NET, 1201–1202autogenerated, 1025AutoIncrement property, 787–788AutoIncrementSeed property, 787–788AutoIncrementStep property, 787–788AutoLotConnectedLayer namespace, 780AutoLotDAL namespace, 834AutoLotDAL.AutoLotDataSetTableAdapters

namespace, 834AutoLotDAL.dll assembly, 809, 811, 813, 834, 840,

911, 1180AutoLotDAL.dll library, 783, 844, 1187AutoLotDatabase class, 846, 852AutoLotDatabase namespace, 849AutoLotDataSet type, 832autoLotDB.cs file, 849autoLotDS object, 816AutoLotService type, 912Automatic property, 907AutoPostBack property, ASP.NET web controls,

1208–1209AutoResetEvent type, 931AutoReverse property, 1138, 1140

BBackColor property, WebControl base class, 1213Background property, 1108, 1148, 1154BackgroundWorker component, 612, 614–615*.baml files, 1026base class, 186, 192–194, 1193base class/derived class casting rules

as keyword, 211is keyword, 211–212overview, 210–211

base keyword, 192, 1254BaseAddresses property, 892baseAddresses scope, 891<baseAddresses> region, 891BaseDirectory( ) method, System.AppDomain, 572BasedOn property, 1150BasePriority, ProcessThread type, 568BaseStream property, 682basicHttpBinding bindings, 899BasicHttpBinding class, 882, 900BasicHttpBinding option, 882<basicHttpBinding> subelement, 900

BasicSelections( ) method, 466*.bat file, 72Beep( ) property, 76BeginAnimation( ) method, 1139, 1141BeginCatchBlock( ) method,

System.Reflection.Emit.ILGenerator, 650BeginClose( ) method, 892BeginEdit( ) method, 805Begin/End asynchronous invocation pattern, 909BeginExceptionBlock( ) method,

System.Reflection.Emit.ILGenerator, 650BeginFinallyBlock( ) method,

System.Reflection.Emit.ILGenerator, 650BeginInvoke( ), multithreaded applications,

587–588, 591–593BeginLabel( ) method,

System.Reflection.Emit.ILGenerator, 650BeginLocal( ) method,

System.Reflection.Emit.ILGenerator, 650BeginOpen( ) method, 892BeginScope( ) method,

System.Reflection.Emit.ILGenerator, 650<BeginStoryboard> element, 1141BeginTime property, 1138BeginTransaction( ) method, DbConnection,

ADO.NET, 757<behavior> element, 893, 895behaviorConfiguration attribute, 894Bin folder, 1190–1191Binary Application Markup Language (BAML),

1026–1028binary code reuse, 475binary formats, 1316binary opcodes, 619–620binary operators, overloading, 389–391binary resources, 1145BinaryFormatter

deserialization, 719serialization, 717

BinaryFormatter type, 714, 797BinaryReader class, 682BinaryWriter class, 682binding, 880, 889, 1103, 1111<bindings> element, 893, 900BindingSource component, 824Bitmap type, 986BitmapImage object, 1129black box programming, 165blue screen of death, 1001<body> section, 1168, 1170booc compilers, 1321bool data type, 80bool keyword, 82Boolean member variable, 1026Border control, 1056BorderColor property, WebControl base class, 1213BorderStyle property, WebControl base class, 1213BorderWidth property, WebControl base class,

1213

■INDEX 1337

Finditfasterathttp://superindex.apress.com

/

Page 56: Appendixes - Springer

Bottom property, 1086Bounds property,

System.Windows.Media.Geometry baseclass, 1131

boxing and unboxingCIL code, 318–319generics issues, 316, 318–319InvalidCastException, 319.NET 1.1 solution, 319, 321–322.NET 2.0 solution, 323

bread crumbs, 1221break keyword, 101Browser Applications (XBAPs), XAML, 1004Browser member, HttpRequest Type, 1196Browser property, 1196browser statistics in HTTP Request processing,

ASP.NET, 1196browser-based presentation layers, 1163Brush property, 1132Brush type, 989, 1036Brushes utility class, 989btnClickMe type, 1148btnClickMeToo type, 1148btnExitApp_Clicked( ) method, 1025btnGetColor Button object, 1079btnGetColor_Click( ) method, 1079btnGetGameSystem property, 1078btnShowAppVariables Button type, 1256bubbling event, 1065BufferedGraphics type, 987BufferedStream type, input/output, System.IO, 661BufferHeight property, 76BufferWidth property, 76bugs, description, 219BuildCar.aspx content page, 1228BuildMenuSystem( ) helper function, 960BuildTableRelationship( ) method, 817built-in style engine, 1002business process, 917, 925Button Click event handler, 1083Button control, 1056, 1058, 1065Button object, 1312Button property, 975–976Button type, 612, 707, 817, 950, 1022, 1078, 1081,

1108, 1138, 1142, 1148, 1150, 1154,1156–1157, 1182–1183, 1188, 1234, 1240,1248, 1258, 1274

Button widget, 1210<Button> element, 1082ButtonBase class, 1069ButtonBase-derived type, 1071<Button.RenderTransform> scope, 1144by operator, 463By property, 1138ByRef keyword, 111ByRef parameters, 1296byte data type, 80ByVal keyword, 111, 1296

CC language deficiencies, 4C# programming tools, 1319C++ language deficiencies, 4<c> code comment, XML Elements, 177cache mechanism, 1263Cache member variable, 1260Cache object, 1259Cache property, HttpResponse Type, 1198Cache property, Page Type, 1195CacheDependency type, 1261CacheItemRemovedCallback delegate target

method, 1263CacheItemRemovedCallback delegate type, 1261Cache.NoSlidingExpiration field, 1261CacheState web application, 1259CalcInteropAsm.dll interop assembly, 1297Calculate Permissions button, 708CalculateAverage( ) method, 111callback interfaces

event interface, 305, 307–308overview, 341sink object, 305, 307–308two-way conversation, 304

CallbackContract property, 887CanBeNull property, 848CancelButton property, 971, 981CancelEdit( ) method, 805CancelEventArgs property, 974CancelEventHandler delegate, 973CanExecute event, 1101CanHelpExecute( ) method, 1102Canvas control, 1056Canvas panel control, 1084Canvas type, 1092<Canvas> tag, 1085Canvas.Bottom property, 1086Canvas.Left property, 1086Canvas.Left value, 1086Canvas.Right property, 1086Canvas.Top property, 1086Canvas.Top value, 1086Caption property, 787–788CaretIndex property, 1082carIDColumn DataColumn object, 793carIDColumn object, 789carInventoryGridView object, 808CarLibrary.dll assembly, 691Cars example database, ADO.NET, 744carsDataSet.xml file, 796carsInventoryDS DataSet object, 793CarsXmlDoc resource, 1114CaseSensitive member, 793CaseSensitive property, 785casting operations

explicit cast, 209implicit cast, 210

casting operator ( ), 96

■INDEX1338

Page 57: Appendixes - Springer

catch keyword, 98CenterToScreen( ) method, 972ChangeDatabase( ) method, DbConnection,

ADO.NET, 757Channels property, 897char keyword, 85char type, 83CheckBox control, 1056, 1102CheckBox type, 1070Checked events, 1070/checked flag, 99checked keyword, 97, 100checked scope, 100CheckPassword( ) method, 1083child class, 186ChildRelations member, 793Circle type, 204–205Class attribute, MainWindow, 1022class constructors, 173

default constructor revisited, 146–147defining custom constructors, 145–146overview, 144role of default constructor, 144–145

Class Designer toolbox, 190Class Details window, 190class diagram file, 182Class Diagram icon, 189class diagrams, revising, 189–190class directive, common intermediate language

(CIL), 631–632class hierarchy, 286class ID (CLSID), 1306class interface, 1307Class keyword, 141class library definition, 481Class Library project, 430class name prefix, 173Class suffix, 1288class types, 17, 141, 432Class1.cs file, 885classes, differences from objects and references,

245classic ASP and ASP.NET, 1175, 1177classical inheritance, 160, 186[ClassInterface] attribute, 1306, 1308, 1311ClassInterfaceType.AutoDual class interface, 1308Class-suffixed types, 1288Clear( ) member, HttpApplicationState type, 1255Clear( ) method, 76, 119, 785, 958, 987, 1199Click event, 707, 817, 950, 960, 967, 970, 1014, 1060,

1064, 1071, 1078, 1094, 1114, 1157, 1173,1182, 1207, 1234

Click event bubbles, 1065Click event handler, 802–803, 818, 981, 985, 1067,

1081, 1139–1140, 1182, 1197, 1199, 1212,1246, 1256, 1262, 1265, 1268, 1274

ClickMode property, 1069ClickMode.Hover value, 1069

ClickOnce deployment, 707–708Clicks property, 975client subelement, 894<client> element, 897ClientBuild.rsp file, 1327client-side proxy/*.config file, 894client-side scripting, 1172–1174, 1185ClientTarget property, Page Type, 1195Clone( ) method, 271, 786cloneable objects (ICloneable), 295, 297–299CloneMe( ) method, 271Close( ) method, 160, 676, 678, 682, 891, 972Closed event, 972CloseMainWindow( ) method,

System.Diagnostics.Process, 565CloseTimeout property, 892*.cls file, 1295, 1300CLSCompliant attribute, 543CoCar class, 1299_CoCar interface, 1303__CoCar_BlewUpEventHandler type, 1304__CoCar_Event type, 1304__CoCar_SinkHelper type, 1304CoCarClass object, 1303code access security

observing in action, 696–697role of code groups, 692–695role of evidence, 689–692role of permission sets, 695

Code Access Security (CAS), 687–689Code activity, 927–928code groups, role of in code access security,

692–693, 695code libraries, 481, 1191<Code> element, 1022–1023CodeActivity, WF, 921<codeBase> element, 687code-behind model, 1029–1030, 1177, 1179,

1186–1188CodeFile attribute, 1187CodePage attribute, <%@Page%> directive, 1184<codeSubDirectories> element, 1191collection initialization, 439, 441collections

ICollection interface, 310IDictionary interface, 311IDictionaryEnumerator interface, 311IList interface, 311overview, 269

CollectionsUtil member,System.Collections.SpecializedNamespace, 316

ColorAnimation type, 1137ColorConverter type, 1107coltsOnlyView type, 806[Column] attribute, 847ColumnAttribute property, 848ColumnAttribute type, 845

■INDEX 1339

Finditfasterathttp://superindex.apress.com

/

Page 58: Appendixes - Springer

<ColumnDefinition> element, 1090ColumnMapping property, 787ColumnName property, 787COM Callable Wrapper (CCW), 1283, 1306COM IDL (interface definition language) data

types, 1290COM Interop option, 1310COM library statement, 1295Combine( ) method,

System.MulticastDelegate/SystemDelegate, 345

ComboBox control, 1056ComboBox type, 1078<ComboBoxItem> element, 1076ComCalc COM object, 1287, 1295_ComCalc interface, 1296ComCalc object, 1286ComCalcClass object, 1288ComCalc.cls class file, 1284ComCallableDotNetServer.tlb, 1311[ComClass] attribute, 1306comContracts subelement, 894Command object, ADO.NET, 733, 759–760command prompt, Visual Studio 2003, 36Command property, 1069CommandBinding object, 1101command-line arguments, processing, 1015–1016CommandParameter property, 1069CommandTarget property, 1069CommandTimeout, DbCommand, ADO.NET, 760Common dialog boxes, 956Common Intermediate Language (CIL), 92, 94,

1316advantages of learning, 617–618assembly directive, 630attributes, 619benefits, 15binary opcodes, 619–620C# vs. VB.NET, 13–14class directive, 631–632code explained, 623–624code labels, 624–625compiler flags, 626compiling code, 626–627compiling to specific platforms, 15complete example program, 643, 645–647current object parameter, 642defining the current assembly, 630directives, 618enums, 633externally referenced assemblies, 629field directive, 636generics in, 633–634ilasm.exe compiler, 617interfaces, 632iteration, 642just-in-time (JIT) compiler, 15locals directive, 640

mapping C# types to CIL types, 635mapping parameters to variables, 641maxstack directive, 640method parameters, 638methods, 637mnemonics, 619–620modifying code, 621, 623–626module directive, 630mresources directive, 630namespace directive, 630new keyword, 247opcodes, 619, 638overview, 13, 617peverify.exe tool, 629as programming language, 617properties, 637pushing and popping from the stack, 620–621round-trip engineering, 621, 623–626saving CIL code using ildasm.exe, 621, 623–624stack-based programming, 620–621structures, 632–633subsystem directive, 630token set of, 618type constructors, 636–637using SharpDevelop, 627variables, local, 640virtual execution stack, 620

Common Language Infrastructure (CLI),1315–1316

Common Language Runtime (CLR), 22, 1283Common Language Specification (CLS)

compliance verification, 21–22overview, 20Rule 1, 21–22

Common Type System (CTS), 870, 1177adornments, 19class types, 17delegate types, 19enumeration types, 18–19interface types, 18intrinsic types, 19overview, 17structure types, 18type members, 19

commonBehaviors subelement, 894companyLogo Image control, 1145Compare( ) method, 87CompareExchange( ) method, 607CompareValidator control, ASP.NET, 1231, 1233compilation cycle, ASP.NET 2.0

multifile pages, 1193overview, ASP.NET 2.0, 1192single-file pages, 1192

<compilation> element, 1189compile time, 174<Compile> elements, 1029compiler error, 81compiler-generated anonymous method, 452

■INDEX1340

Page 59: Appendixes - Springer

CompilerOptions attribute, <%@Page%> directive,1184

Complain( ) method, 154Component Object Model (COM), 5component tray, 824ComponentsCommands object, 1100ComSvcConfig.exe command-line tool, 883ComUsableDotNetServer.dll, 1310concurrency, multithreaded applications, 584,

602–607Condition property, Properties window, 928conditional code compilation, 435ConditionalEventArgs type, 928ConditionedActivityGroupActivity, WF, 921*.config file, 687, 698, 825, 870, 872, 879, 894, 900/config: option, 896<configuration> element, 1191ConfigurationManager type, 825ConfigurationName property, 887ConfigureAdapter( ) method, 811–812Connect( ) method, IComponentConnector

interface, 1026connected layer, ADO.NET, 755–756Connection, DbCommand, ADO.NET, 760connection objects, ADO.NET, 756–758ConnectionString property, 825, 1225<connectionString> element, 1273ConnectionStringBuilder object, ADO.NET,

758–759<connectionStrings> element, 754–755, 822, 825,

1204ConnectionTimeout( ) method, DbConnection,

ADO.NET, 757Console Application, 415Console class, 70Console type, 76console user interface (CUI), 76ConsoleClientApp.exe, 1326ConsoleClientApp.exe assembly, 1327Console.ReadLine( ) method, 70Console.WriteLine( ) method, 77, 151, 928Const keyword, 173constant data, 173–174Constraints member, 793constructor chaining, 149constructor logic, 152ConstructorBuilder, System.Reflection.Emit

namespace, 649constructors, 93, 141, 144ContainerControl class, 971containment/delegation, 185, 196

nested type definitions, 197–199overview, 196–197

Contains( ) method, 87Content member, 1061Content property, 1007, 1022, 1058, 1070, 1084,

1103, 1105, 1132Content value, 1080

ContentControl base class, Window type, 1007ContentEncoding property, HttpResponse Type,

1198ContentPlaceHolderID value, 1223<ContentPresenter> element, 1156ContentType property, HttpResponse Type, 1198context-agile, 578–579context-bound, 578–579Context.Cache.Insert( ) method, 1260ContextMenu control, 1056continue keyword, 101contract element, 889contravariance, delegates, 359Control class, 270, 971control commands, 1099Control parent class, 975, 1194Control property, 977control state, 1251control templates, 1156Control type, 1213ControlBox property, 971ControlContent member, 1061controls, ASP.NET, 1243Controls member, System.Web.UI.Control, 1209Controls property, 958, 970, 1209–1210ControlsCollection class, 958–959ControlState property, 1251ControlTemplate base class, 1156<ControlTemplate> element, 1156, 1159ControlToValidate member, ASP.NET validator,

1231ControlToValidate property, 1232Convert class, 100Convert( ) method, 1106ConvertBack( ) method, 1106Converter property, 1107cookies creation, ASP.NET, 1267Cookies member, HttpRequest Type, 1196cookies overview, ASP.NET, 1267Cookies property, HttpResponse Type, 1198Copy( ) method, 786, 793CopyTo( ) method, 119, 669CopyToDataTable<T>( ) extension method, 842Core infrastructure, 956CoreLibDumper class type, 1323CoreLibDumper.dll assembly, 1323, 1325, 1327Count member, HttpApplicationState type, 1255Count method, 958covariance, 358–359, 362Create( ) method, FileInfo class, System.IO, 669Create( ) subroutine, 1299CreateDataReader( ) method, 795, 838CreateDataTable( ) method, 800CreateDataView( ) method, 806CreateDirectory( ) method, 703, 706CreateFunctionalXmlDoc( ) method, 860CreateFunctionalXmlElement( ) method, 859CreateRectVisual( ) helper method, 1122

■INDEX 1341

Finditfasterathttp://superindex.apress.com

/

Page 60: Appendixes - Springer

CreateText( ) method, FileInfo class, System.IO,669, 672

CreateWorkflow( ) method, 931CreationTime property, FileSystemInfo class, 663Credentials property, 892*.cs file, 896, 927csc.exe compiler, 35

@ symbol (response files), 41command-line flags, 37–38compile parameters, 37–38default response file (csc.rsp), 41–42first C# application, 37mscorlib.dll, 38multiple external assemblies, 39multiple source files, 39–40/noconfig command-line flag, 41–42/nostdlib command-line flag, 38/out command-line flag, 37reasons for using, 36–37/reference command-line flag, 39referencing external assemblies, using

keyword, 38response files, 40–41/target command-line flag, 37wildcard character, 40

CSharpComClient, 1285*.csproj file, 1023, 1030, 1190CssClass property, WebControl base class, 1213CssStyle property, 1237CType( ) function, 211curly brackets, 115currBalance field, 154Current property, Application type, 1006currentColor member variable, 994CurrentContext property, Thread type, 594currentShape variable, 993–994CurrentSize member, 703CurrentThread property, Thread type, 594–596currentVideoGames local variable, 454currInterestRate class, 154currInterestRate variable, 157currValue type, 1072Cursor property, 1096custom constructor, 128custom exceptions, structured exception handling,

231, 233–234custom interfaces, defining, 272custom namespaces, 475–476custom parameters, 931custom type conversion

CIL special names, 403–404conversions among related class types, 397–398explicit keyword, 398–399, 401implicit conversions, 397implicit keyword, 398–399, 401–403numerical conversions, 397

custom view states, state management in ASP.NET,1250

custom web controls, 1216CustomAttributeBuilder, System.Reflection.Emit

namespace, 649CustomBinding type, 881<customErrors> element, web.config File, 1204CustomValidator control, ASP.NET, 1231

DD string, 78dash style, 1130DashStyle object, 1130data adapter, 783data binding model, 1055data caching, ASP.NET, 1259, 1261, 1263data contracts, 875, 910Data property, System.Exception, 222, 229–230data providers, ADO.NET, 733–734data templates, 1080, 1111data type conversions, 95, 100DataAdapter object, ADO.NET data providers, 734/database option, 848Database property, DbConnection, ADO.NET, 757DatabaseReader class, 138, 160DataBind( ) method, System.Web.UI.Control in

ASP.NET, 1209data-binding engine, 1002data-centric controls, 1213data-centric single-file test page

adding data access logic, 1182–1183designing the UI, 1181–1182manually referencing AutoLotDAL.dll, 1180overview, 1180role of ASP.NET directives, 1183–1185

DataColumn object, 784, 788DataColumn type, 787_DataConnector interface, 1295DataContext property, 1104, 1111DataContext type, 844–846DataContext-derived type, 846, 852–853[DataContract] attribute, 910dataGridColtsView object, 808dataGridColtsView type, 806DataGridView control, 798DataGridView object, 814DataGridView type, 806DataGridView widgets, 815DataGridViewRowPostPaintEventArgs parameter,

808[DataMember] attribute, 910DataReader object, ADO.NET data providers, 733DataRelation object, 814, 816DataRelation, System.Data, ADO.NET, 737DataRelation type, 784DataRelationCollection collection, 784DataRow class, 784, 805DataRow.AcceptChanges( ) method, 792DataRow.BeginEdit( ) method, 792DataRow.CancelEdit( ) method, 792

■INDEX1342

Page 61: Appendixes - Springer

DataRow.EndEdit( ) method, 792DataRowExtensions member, 840DataRow.GetChildRows( ) method, 819DataRow.RejectChanges( ) method, 792DataRows type, 837DataRowState property, 792DataRowVersion property, 793DataSet member, 793DataSet objects, 783DataSetName property, 785DataSets type, 837DataSource property, 757, 801, 807DataSourceID property, 1221, 1224–1225DataTable class, 828DataTable object, 912DataTable.AcceptChanges( ) method, 802DataTableCollection collection, 784DataTableExtensions type, 840DataTable.NewRow( ) method, 790DataTableReader property, 795DataTableReader, System.Data, ADO.NET, 737DataTables type, 837<DataTemplate> element, 1112<DataTrigger> element, 1142DataType property, 787DataTypeFunctionality( ) method, 86DateTime structure, 94DateTime type, 83DbCommand, ADO.NET, 760DbConnection, ADO.NET, 757DbDataAdapter base class, 808DbDataReader object, ADO.NET, 760–761DbParameter, ADO.NET, 767DbType property, 767, 848Deactivate event, 972debugging, 215, 626, 1188DecelerationRatio property, 1138DeclareImplicitVars( ) method, 416Decrement( ) method, 607deep copy, cloneable objects (ICloneable), 299default constructor, 128, 144default interface, 1295default keyword, generics, 331Default value, 792Default Web Site node, 1165[default] interface, 1301default.aspx content page example, ASP.NET,

1222–1224Default.aspx file, 1182, 1193, 1241, 1274default.htm file, 1173–1174defaultValue attribute, Profile Data, 1274DefaultValue property, 787DefaultView member, 793#define, preprocessor directive, 411, 413–414DefineEnum( ) method, ModuleBuilder type, 653DefineResource( ) method, ModuleBuilder type,

653DefineType( ) method, ModuleBuilder type, 653

Delay property, 1071DelayActivity, WF, 921delegates

asynchronous call, 342–344CIL code for simple example, 346compared with C-style callbacks, 341complex example, 353–354contravariance, 359covariance, 358–359, 362delegate keyword, 342, 345, 1304description, 341–342example, 348–351information in, 341–342multicasting, 344–345, 351–353and multithreaded applications, 585, 587NullReferenceException, 350–351overview, 341as parameters, 354–357simple example, 345–346synchronous call, 342type safe, 347–348

delegation. See containment/delegationDelete( ) method, 663, 669, 790, 801DeleteCommand property, 812Deleted value, 791DeleteDirectory( ) method, 703DeleteFile( ) method, 703deleting records, ADO.NET, 765Delta property, 975dependency property, 1060, 1137DependencyObject type, 1139DependencyProperty object, 1062DependencyProperty.Register( ) method, 1062deployment, .NET runtime, 31–32derived class, 186derived types, 270descending operator, 463, 468Description property, 907*.Designer.cs file, 926, 964, 983desktop markup, 1000Detached value, 791developing software

as a C++/MFC programmer, 4as a COM Programmer, 5as a C/Win32 programmer, 3as a Java/J2EE Programmer, 4as a Visual Basic 6.0 programmer, 4as a Windows DNA Programmer, 5–6

DevX website, 1331diagnostics subelement, 894DialogResult property, 1114DialogResult type, 974DialogResult value, 982Dictionary object, 932Dictionary<string, object> type, 932differences, classes, objects, references, 245digital signatures and strong names, 505–506direct event, 1065

■INDEX 1343

Finditfasterathttp://superindex.apress.com

/

Page 62: Appendixes - Springer

Direction property, ADO.NET DbParameter, 767Directory type, System.IO, 667DirectoryInfo class

Create( ), CreateSubdirectory( ) methods, 663,666

Delete( ) method, 663GetDirectories( ) method, 663GetFiles( ) method, 663, 665MoveTo( ) method, 664Parent property, 664Root property, 664

DirectX, 1000DirectX API, 1000DirectX engine, 1001disco utility, 1322DiscreteDoubleKeyFrame type, 1144DiscreteStringKeyFrame type, 1143DiscreteXXXKeyFrame type, 1142[DispId] attribute,

System.Runtime.InteropServices, 1306Display member, ASP.NET validator, 1231Display property, 1235DisplayAsmEvidence( ) method, 690DisplayDefiningAssembly( ) method, 425DisplayMemberBinding data binding value, 1114disposable objects, 259–262Dispose( ) method, 259, 964, 989Distributed Component Object Model (DCOM),

868*.dll assemblies, 946DLL hell, 5*.dll server, 1284DllImport attribute, 543, 1284/doc compiler flag, 179DockPanel control, 1056, 1084<DockPanel> element, 1094, 1096, 1109DockPanel.Dock value, 1092DOCTYPE processing instruction, 1168Document Object Model (DOM), ASP.NET,

1172–1173documenting VB 2005 source code via XML,

176–180Domain Name Service (DNS), 1163DomainUnload event, System.AppDomain, 573,

576–577DontUseCoreLibDumper.dll assembly, 1327dot operator and references, 246DotNetCalc class, 1308–1309, 1311_DotNetClass interface, 1311dotnetfx.exe, .NET runtime deployment, 31–32double data type, 81double type, 111double value, 1130DoubleAnimation object, 1137DoubleAnimation type, 1138–1139<DoubleAnimation> element, 1142DoubleAnimationUsingKeyFrames type, 1144DoubleClick event, 970

DoubleConverter type, 1107do/while statement, 102download cache, 485Download Now button, 1318DoWork event, 614DragDrop event, 970DragEnter event, 970DragLeave event, 970DragOver event, 970Draw( ) method, 205, 283, 286DrawArc( ) method, 987DrawBeziers( ) method, 987DrawCurve( ) method, 988DrawEllipse( ) method, 988DrawIcon( ) method, 988DrawIn3D( ) method, 279DrawingBrush type, 1127DrawingContext object, 1122Drawing-derived types, 1120, 1130DrawingGroup type, 1130, 1133DrawingImage object, 1133DrawingVisual type, 1122DrawLine( ) method, 988–989DrawLines( ) method, 988DrawPath( ) method, 988DrawPie( ) method, 988DrawRectangle( ) method, 988DrawRectangles( ) method, 988DrawString( ) method, 988–989DriveInfo class, System.IO, 668–669DriveInfo type, input/output, System.IO, 662DriveInfoApp.exe application, 697driverInfo property, 1303DropDownItems property, 960DumpTypeToFile( ) method, 1323duplex messaging, 882Duration property, 1138–1139, 1144dynamic assemblies

ConstructionBuilder example, 654–655definition, 648emitting a method, 655–656emitting type and member variables examples,

654overview, 617vs. static assemblies, 648using a dynamically generated assembly,

656–657dynamic loading, 536–537

Ee string, 78ECMA standardization, .NET Framework, 32ECMA-334, 1316ECMA-335, 1316ECMA-compatible implementation, 1330EditingCommands object, 1100ElementName value, 1103#elif, preprocessor directive, 411–413

■INDEX1344

Page 63: Appendixes - Springer

Ellipse object, 1111Ellipse types, 1066, 1136, 1156EllipseGeometry type, 1131#else, preprocessor directive, 411–413else statement, 103Emit( ) method,

System.Reflection.Emit.ILGenerator, 650EmitCall( ) method,

System.Reflection.Emit.ILGenerator, 650emitting a dynamic assembly example, 650–652Emitting HTML, ASP.NET, 1199EmitWriteLine( ) method,

System.Reflection.Emit.ILGenerator, 650empAge using property syntax, 168Employee class, 165EmpType enumeration, 121Enable Click Once Security Settings check box, 708EnableClientScript member, ASP.NET validator,

1231Enabled property, WebControl base class, 1213EnableTheming attribute, <%@Page%> directive,

1184EnableTheming member, System.Web.UI.Control,

1209EnableTheming property, System.Web.UI.Control

in ASP.NET, 1209EnableViewState attribute, <%@Page%> directive,

1184, 1249EnableViewState property, 1250encapsulation, 141, 160

class properties, 168–170controlling visibility levels of property get/set

statements, 170–171get, set properties vs. accessor and mutator

methods, 168–170internal representation of properties, 169–170overview, 164–165read-only and write-only properties, 171read-only class properties, 171Shared properties, 171–172static class properties, 171using traditional accessors and mutators,

165–166using type properties, 167–168visibility of get/set statements, 170write-only class properties, 171

End construct, 206End keyword, 141End( ) method, 1199EndClose( ) method, 892EndEdit( ) method, 805EndExceptionBlock( ) method,

System.Reflection.Emit.ILGenerator, 650#endif, preprocessor directive, 411–413EndInvoke( ), multithreaded applications, 587–588EndOpen( ) method, 892<endpoint> element, 884, 889, 894, 897#endregion, preprocessor directive, 411

EndScope( ) method,System.Reflection.Emit.ILGenerator, 650

EnforceConstraints property, 785Enter key, 202entity classes, 837EntitySet<T> type, 851EnumBuilder, System.Reflection.Emit namespace,

649enumData object, 841Enumerable extension methods, 460, 464enumerable types, 289, 291, 456, 459–461, 471Enumerable.Distinct<T>( ) method, 465Enumerable.Except( ) method, 469Enumerable.OfType<T>( ) method, 458EnumerableRowCollection object, 840Enumerable.Where<T>( ) method, 460Enumerable.Where<T> variable, 452enumerating controls with Panel control, ASP.NET,

1210enumeration, 18–19, 121Enum.Format( ) method, 124Enum.GetUnderlyingType( ) method, 123enums, common intermediate language (CIL), 633Environment type, 75Environment.GetCommandLineArgs( ) method,

1015Equals( ) method, 87, 91, 213, 215, 441–443, 467equals operator, 466Error event, ASP.NET, 1202%ERRORLEVEL% environment variable, 71ErrorMessage dictionary, 932ErrorMessage member, ASP.NET validator, 1231ErrorMessage property, 933, 1232escape characters, 89event interface, 305, 307–308event keyword, 363event trigger, 1141–1142EventArgs type, 961EventBuilder, System.Reflection.Emit namespace,

649event-driven entity, 1208EventDrivenActivity, WF, 921EventHandler<T> delegate, 369EventHandlingScopeActivity, WF, 921EventInfo class, System.Reflection namespace, 528events

compared with delegates, 362event keyword, 362example, 363–364explanation, 364–365listening to incoming events, 365–366Microsoft recommended pattern, 367–368overview, 341registration, 365–367

<EventTrigger> element, 1142evidence, role of in code access security, 689–692<example> code comment, XML Elements, 177Exception class, 222, 230

■INDEX 1345

Finditfasterathttp://superindex.apress.com

/

Page 64: Appendixes - Springer

_Exception interface, 222<exception> code comment, XML Elements, 177exceptions, 219, 240Exchange( ) method, 607ExecuteAssembly( ), System.AppDomain, 572ExecuteCode property, 927, 929, 936Executed event, 1101ExecuteMethodCall( ) method, 852ExecuteNonQuery( ) method, 760, 853ExecuteReader( ), DbCommand, ADO.NET, 760ExecuteScalar( ), DbCommand, ADO.NET, 760ExecuteXmlReader( ), DbCommand, ADO.NET, 760existing class definitions, 160Exit event handler, 1023ExitCode property, 76ExitCode, System.Diagnostics.Process, 564ExitEventArgs type, 1012ExitEventHandler delegate, 1012ExitTime, System.Diagnostics.Process, 564ExpandDirection property, 1074Expander control, 1056Expander type, 1058, 1074, 1097Expander widget, 1094explicit casting, 96, 209, 276–277explicit keyword, custom type conversion,

398–399, 401Expression Blend, 1052–1053Expression property, 787ExtendedProperties property, 785Extensible Application Markup Language (XAML),

999attached properties, 1038–1039Browser Applications (XBAPs), 1004building XAML-free WPF applications

creating simple user interface, 1013–1015,1021

extending Window class type, 1013overview, 1011–1013

defining application object in, 1023, 1033defining MainWindow in, 1022–1023elements and attributes, 1035experimenting with using XamlPad, 1032mapping to C# code, 1025–1026markup extensions, 1039–1041overview, 1021–1022processing at runtime, 1048–1052processing XAML files via msbuild.exe,

1023–1024property-element syntax, 1036–1037type converters, 1039

extension methods, 453Extension property, FileSystemInfo class, 663Extensions class, 432

FF or f string format, .NET, 78FaultHandlerActivity, WF, 921field directive, common intermediate language

(CIL), 636

FieldBuilder, System.Reflection.Emit namespace,649

FieldInfo class, System.Reflection namespace, 528Field<T>( ) extension method, 841File class, System.IO, 673, 675File System option, 1188File Transfer Protocol (FTP), 1164FileExit_Click( ) method, 1095FileInfo class, System.IO, 669–672FileName property, 997FilePath member, HttpRequest Type, 1196FileStream class, System.IO, 676–677FileStream type, input/output, System.IO, 662FileSystemInfo class, 663FileSystemWatcher class, System.IO, 683, 685FileSystemWatcher type, input/output, System.IO,

662Fill( ) method, 808, 810, 813Fill property, 1125FillBehavior property, 1138FillContains( ) property, 1131Filter property, 997finalizable objects, 256finalization details, 258Finalize( ) method, 213, 256–258finally block, structured exception handling,

239–240finalPoint variable, 437FindMembers( ) method, System.Type class, 529FindResource( ) method, 1155FinishButtonClick event, 1229firstPoint variable, 437fixed keyword, 409–410float data type, 81float variable, 81flow documents, 1083Flush( ) method

ASP.NET HTTP Response, 1199BinaryWriter class, 682HttpResponse Type, 1199Stream class, System.IO, 676TextWriter, System.IO, 678

Font property, WebControl base class, 1213FontSize property, 1148, 1154Foo( ) method, 426for loop, 73for statement, 100forcing, 253–254forcing garbage collection, 255foreach keyword, 73, 101foreach looping construct, 417ForeColor member, ASP.NET validator, 1231ForeColor property, WebControl base class, 1213Foreground property, 1154ForegroundColor property, 76Form class, 957, 978form control declarations, ASP.NET, 1185form data, access in ASP.NET, 1197–1198Form event, 707

■INDEX1346

Page 65: Appendixes - Springer

Form member, HttpRequest Type, 1196Form property, 1197form statement, 1195Form type, 968<form> element, 1169, 1174, 1181, 1185, 1210,

1222–1223, 1249Form1.cs file, 798, 979, 991Form1.cs icon, 963Format( ) method, 87FormatException exception, 78FormatNumericalData( ) method, 78FormBorderStyle property, 971, 979FormBorderStyle.FixedDialog dialog box, 979Form-derived class, 1245Form-derived type, 815, 958, 963FrameworkElement base class, 1080, 1123, 1134FrameworkElement class type, 1062FrameworkElement element, 1119FrameworkElement member, 1061FrameworkPropertyMetadata object, 1063Friend access modifier, 163from operator, 463, 465From property, 1138–1139FullName property, FileSystemInfo class, 663fully qualified names, 213, 476–478Func<> delegate, 459Func<> type, 464Func<T, K> type, 461[Function] attribute, 852/functions option, 848FunWithBrushes.xaml file, 1129FunWithDrawingGeometries.xaml file, 1134FxCop development tool, 65

Ggacutil utility, 1322, 1325garbage collection

AddMemoryPressure( ) method, 252AddRef( ) not required, 247application domain, 256application roots, 249code example, 252–255Collect( ) method, 252–255CollectionCount( ) method, 252compared with C++, 247finalizable objects, 256finalization details, 258forcing, 253–255GetGeneration( ) method, 252GetTotalMemory( ) method, 252MaxGeneration property, 252object generations, 251–252object graph use, 249–250overriding finalize( ), 256–258overview, 245PInvoke, 256reachable objects, 246Release( ) not required, 247

SuppressFinalize( ) method, 252System.GC, 252threads suspended, 248timing of, 247unmanaged resources, 252, 256–258, 262WaitForPendingFinalizers( ) method, 252–253when heap objects are removed, 246, 248

*.g.cs file, 1029, 1059GDI+, System.Drawing.Graphics class, 987generic method

custom, creating, 327example code, 328–329type parameter omission, 328–329

generic mono C# compiler (gmcs), 1321generics

base classes, 337boxing and unboxing issues, 316, 318–319,

321–323constraining type parameters using where,

334–336constraints for generic type parameters,

334–336custom generic collections, 332–334default keyword, 331delegates, 360–361generic methods, 327–329interfaces, 338lack of operator constraints, 336–337overview, 309System.Collections.Generic.List<>, 322–324uses of, 316, 318–319, 321–322

Geometry property, 1132<GeometryDrawing> type, 1131<GeometryGroup> type, 1133GET and POST, ASP.NET, 1174–1175Get button, 1246Get scope, 167get_SocialSecurityNumber( ) method, 170get_XXX( )/set_XXX( ) method, 169GetAllFords( ) method, 863GetAllInventory( ) method, 814GetAndValidateUserName( ) method, 929, 933GetAssemblies( ), System.AppDomain, 572GetBoolFromDatabase( ) method, 138GetChanges( ) method, 786GetChildRelations( ) method, 786GetColumnsInError( ) method, 789GetCommandLineArgs( ) method, 74–75GetConstructors( ) method, System.Type class, 529GetCurrentProcess( ), System.Diagnostics.Process,

565GetCurrentThreadId( ), System.AppDomain, 572GetCylinders( ) method, 1303GetDirectories( ) method, DirectoryInfo class, 663GetDirectoryNames( ) method, 703GetDomain( ), GetDomainD( ) methods, Thread

type, 594GetEnumerator( ) method, 119, 289, 703, 958

■INDEX 1347

Finditfasterathttp://superindex.apress.com

/

Page 66: Appendixes - Springer

GetEvents( ) method, System.Type class, 529GetFactory( ) method, ADO.NET, 750GetFields( ) method, System.Type class, 529GetFiles( ) method, 663, 665, 703GetHashCode( ) method, 213, 216, 441–443, 445,

467GetIDsOfNames( ) method, 1298GetInterfaces( ) method, System.Type class, 529GetIntFromDatabase( ) method, 137GetInventory( ) method, 912, 914GetInvocationList( ) method,

System.MulticastDelegate/SystemDelegate, 345

GetMembers( ) method, System.Type class, 529GetMethods( ) method, System.Type class, 529GetNestedTypes( ) method, System.Type class, 529GetNumberOfPoints( ) method, 272GetObjectData( ) method, 726–727GetParentRelations( ) method, 786GetPetName stored procedure, 849GetProcesses( ), System.Diagnostics.Process, 565GetProperties( ) method, System.Type class, 529GetRandomNumber( ) function, 153GetRenderBounds( ) property, 1131GetSchema( ) method, DbConnection, ADO.NET,

757GetStore( ) method, 703GetStringArray( ) method, 118GetStringSubset( ) method, 470GetSubsets( ) method, 466GetTable( ) method, 846GetTable<T>( ) method, 846GetType( ) method, 117, 123, 213, 272, 441,

529–530GetUserAddress( ) method, 1278GetUserData( ) method, 77GetUserStoreForAssembly( ) method, 703–704GetUserStoreForDomain( ) method, 703–704GetValue( ) method, 1063GetValues( ) method, 126GetVisualChild( ) method, 1122GiveBonus( ) method, 199global assembly cache (GAC), 28, 482, 516, 518,

1310, 1317Global class, 1259Global.asax event handlers in ASP.NET, 1252–1253Global.asax file, 1245, 1250–1251, 1253, 1259<globalization> element, web.config File, 1204globally unique identifiers (GUIDs), 297–299, 1285Global.Session_Start( ) method, 1266GlyphRunDrawing type, 1130godmode option, 74goto keyword, 101<GradientStop> type, 1129graphical user interface (GUI), 76, 955Graphics object, 808, 1118Graphics type, 987GreenStyle property, 1154

Grid control, 1056, 1084Grid type, 1097<Grid> element, 1058, 1071, 1114Grid.Column property, 1090<Grid.ColumnDefinitions> element, 1090Grid.ColumnSpan property, 1109Grid.Row property, 1090<Grid.RowDefinitions> element, 1090<GridSplitter> type, 1091GridView control, 1056, 1224–1225, 1227<GridViewColumns> element, 1114group operator, 463<group> element, 1278GroupBox control, 1056GroupBox type, 817GroupName property, 1073GUID compared with strong names, 505–506[Guid] attribute, 1306, 1309guidgen.exe utility, 1309–1310

HHandle, System.Diagnostics.Process, 564HandleCount, System.Diagnostics.Process, 564Handled property, 977, 1066has-a relationship code example, 196HasChanges( ) method, 786HasContent property, 1008HasControls( ) method, System.Web.UI.Control in

ASP.NET, 1209HasErrors property, 785, 789hash code, 216Hashtable System.Collections class type, 312Hashtable type, 216HasValue property, 137Header property, 1073Headers member, HttpRequest Type, 1196HeaderText property, 1235Height member, 1061Height property, 1062, 1085, 1137, 1213Height value, 1087HelloWebService.asmx file, 871HelloWorld( ) method, 871HelloWorld.asmx file, 872HelpExecute( ) method, 1102HelpLink property, System.Exception, 222, 228–229Hexagon class, 160Hexagon type, 204–205, 272Hide( ) method, 971historical overview of programming

C++/MFC, 4Component Object Model (COM), 5C/Win32, 3Java/J2EE, 4Visual Basic 6.0, 4Windows DNA, 5–6

Horizontal property, 1089HorizontalAlignment property, 1156<host> element, 894

■INDEX1348

Page 67: Appendixes - Springer

*.htm file, 1168, 1170HTML and ASP.NET, overview, 1167HTML document structure, 1168HTML form development, 1169HTML tables, positioning ASP.NET controls using,

1243<html> tag, 1168HTTP Request processing, ASP.NET, 1195–1198HTTP Response, ASP.NET, 1198–1200http:// scheme, 889HttpApplication members, ASP.NET, 1253HttpApplication type, 1207, 1245, 1252, 1254, 1269HttpApplication-derived type, 1256, 1263HttpApplicationState members, ASP.NET, 1255HttpApplicationState type, 1254–1256, 1258HttpBrowserCapabilities object, 1196HttpCookie type, 1266HttpCookie.Expires property, 1268HttpMethod member, HttpRequest Type, 1196HttpRequest class type, 1196HttpRequest.Cookies property, 1268HttpRequest.Form property, 1197HttpRequest.NameValueCollection type, 1212HttpRequest.QueryString property, 1197HttpResponse type, 1198HttpResponse.Write( ) method, 1199HttpResponse.WriteFile( ) method, 1199HttpServerUtility.ClearError( ) method, 1203HttpServerUtility.GetLastError( ) method, 1203HttpSessionState class type, 1254HttpSessionState object, 1247, 1263, 1266, 1272HybridDictionary member,

System.Collections.SpecializedNamespace, 316

HyperLink widget, 1210Hypertext Markup Language. See HTMLHypertext Transfer Protocol. See HTTP

IIasyncResult interface, 342–344IAutoLotService.cs file, 911IBasicMath.cs file, 901ICloneable interface, 134, 213, 271, 296, 310ICollection System.Collections interface, 310ICollection System.IDictionaryinterface, 311ICollection System.IDictionaryEnumerator

interface, 311ICollection System.IList interface, 311ICommand interface, 1099IComparer interface, System.Collections, 310IComponentConnector interface, 1026IConnectionPointContainer class, 1291IConnectionPoint, IConnectionPointContainer

class interface, 1307IContainer member variable, 964ICustomFormatter interface, 79ID attribute, 1114

ID member, System.Web.UI.Control, 1209Id, ProcessThread type, 568ID property, System.Web.UI.Control in ASP.NET,

1209Id, System.Diagnostics.Process, 564IDataAdapter, System.Data, ADO.NET, 737IDataParameter, System.Data, ADO.NET, 737IDataReader, System.Data, ADO.NET, 737IDbCommand interface, ADO.NET, 738–739IDbConnection interface, 269–270, 737IDbConnection object, 852IDbConnection-comparable object, 843IDbDataAdapter, IDataAdapter interface,

ADO.NET, 739IDbDataParameter, IDataParameter interface,

ADO.NET, 739IDbDataReader, IDataReader interface, ADO.NET,

740IDbTransaction interface, ADO.NET, 738IdealProcessor, ProcessThread type, 568identity, private assemblies, 499IDictionary interface, System.Collections, 310IDictionaryEnumerator interface,

System.Collections, 310IDispatch interface, 1298IDisposable interface, unmanaged resources,

259–261IDL attributes, 1295IDL library keyword, 1295IDL tokens, 1294IDriverInfo interface, 1300, 1303IDropTarget interface, 270IEightBall interface, 885, 897IEnumerable interface, 101, 310, 321, 453, 458IEnumerable type, 470IEnumerable<T> element, 839IEnumerable<T> interface, 448IEnumerable<T> object, 458IEnumerable<T> variable, 453, 457IEnumerable<T>-compatible object, 464IEnumerator interface, 101, 310, 384IEnumVariant class interface, 1307IErrorInfo, ICreateErrorInfo interface, 1292IErrorInfo, ISupportErrorInfo class interface, 1307#if, preprocessor directive, 411–413if statement, 103IfElse activity, 921, 945IHashCodeProvider interface, System.Collections,

310ilasm utility, 1322ilasm.exe compiler, common intermediate

language (CIL), 617ilasm/ilasm2 compilers, 1321ILGenerator, System.Reflection.Emit namespace,

649IList interface, System.Collections, 310IList System.Collections interface, 310Image control, 1056, 1132

■INDEX 1349

Finditfasterathttp://superindex.apress.com

/

Page 68: Appendixes - Springer

Image property, 985Image type, 987Image widget, 1145ImageAnimator type, 987ImageBrush type, 1127ImageDrawing type, 1130ImageOrderAutoDialog.cs file, 983immediate mode graphics systems, 1117Implements keyword, 1300implicit cast, 210implicit keyword, custom type conversion,

398–399, 401–403implicit typing, 415implicitly typed local arrays, 419<Import> subelements, *.xaml files, 1024in operator, 463, 465[in] attribute, 1296, 1306Include attribute, <ApplicationDefinition>

element, 1024Increment( ) method, 607indexer methods

example, 384IEnumerator, IEnumerable interfaces, 384indexer definitions on interface types, 388indexers with multiple dimensions, 387indexing objects using string values, 385–386internal representation of, 387overloaded, 386overview, 383System.Collection.ArrayList, 384System.Collections.Specialized.ListDictionary,

386this[ ] syntax, 384

inheritance, 160–161, 185adding sealed class, 195–196base keyword in class creation, 192colon operator, 192containment/delegation inheritance model,

196controlling base class creation with MyBase,

192–194has-a relationship code example, 196is-a relationship code example, 190, 192multiple base classes not allowed, 187NotInheritable keyword, 188overview, 185–186, 190–192protected keyword, 194–195regarding multiple base classes, 187–188sealed classes, 195–196, 202specifying parent class, 186–187

inheritance chain, page type in ASP.NET, 1194Inherits attribute, <%@Page%> directive, 1184Init event handler, System.Web.UI.Page base class,

1248Init event, Page type, 1201InitializeComponent( ) method, 926, 963,

1026–1027, 1029, 1101, 1193InitialValue property, 1232

innerEllipse object, 1066InnerException property, System.Exception, 222InnerText property, 1115in-place editing example, ASP.NET, 1227–1228input/output, System.IO

asynchronous I/O, 685–686BinaryReader, BinaryWriter, 682BinaryReader, BinaryWriter types, 661BufferedStream type, 661Directory, DirectoryInfo types, 661–663Directory type, 667DriveInfo class, 668–669DriveInfo type, 662File class, 673, 675File, FileInfo types, 662–663FileInfo class, 669FileStream class, 676–677FileStream type, 662FileSystemWatcher class, 683, 685FileSystemWatcher type, 662MemoryStream type, 662namespace description, 661overview, 661Path type, 662reading from a text file, 679Stream class, 675StreamReader, StreamWriter, 677StreamWriter, StreamReader types, 662StringReader, StringWriter, 680StringWriter, StringReader types, 662writing to a text file, 679

Insert( ) method, 87, 1259InsertAuto( ) method, 913InsertCar( ) method, 912InsertCommand property, 812inserting records, ADO.NET, 764InsertNewCars( ) method, 856installing .NET 3.5 Framework SDK, 35InstallSqlState.sql file, 1271installutil.exe command-line tool, 907Instancing property, 1300int data type, 80int parameter, 95intArray declaration, 116Integer data type, 141Integer parameter, 95IntelliSense, 201interface

in arrays, 281cloneable objects (ICloneable), 295, 297–299colon operator, 274comparable objects (IComparable), 299–300custom, 272–273custom properties and sort types, 304deep copy, 299definition, 269designing hierarchies, 286–287, 289determining using as keyword, 277

■INDEX1350

Page 69: Appendixes - Springer

determining using explicit cast, 276–277determining using is keyword, 277–278enumerable types (IEnumerable and

IEnumerator), 289, 291hierarchies, 286implementing, 275invoking objects based on, 276multiple sort orders (IComparer), 302–303overview, 269shallow copy, 295, 297–298struct, derive from System.ValueType, 274–275System.Collections interfaces, 309System.Object base class, 274types, 432

contrasting to abstract base classes, 270multiple inheritance with, 287–289overview, 18

using as a parameter, 278–280using as a return value, 280–281Visual Studio 2008, 282

interface keyword, 269InterfaceNameClash, 283interfaces and data providers, ADO.NET, 741–742interfaces, common intermediate language (CIL),

632[InterfaceType] attribute,

System.Runtime.InteropServices, 1306Interlocked type, 594, 607intermediate language (IL), 11Intermediate Language Disassembler utility

(ildasm.exe), 90, 490CIL code display, 29icons, 29manifest display, 30overview, 28type metadata display, 30

International Organization for Standardization(ISO), 1316

Internet Information Services (IIS)default web site, 1165description, 1164virtual directories, 878, 1165

Internet Information Services applet, 1165Internet zone, 692, 1004interop assemblies, 1285Interop. prefix, 1287Interop.SimpleComServer.dll assembly, 1287Interrupt( ) method, Thread type, 595Interval property, 1071into operator, 466intrinsic types in CTS, VB.NET, C#, C++, 19Invalidate( ) method, 971, 990, 995InvalidCastException, boxing and unboxing, 319Inventory class, 845inventory content page example, ASP.NET,

1224–1228Inventory entity class, 846, 856Inventory type, 844, 850

<Inventory> element, 862, 1114Inventory.aspx page, 1224–1225, 1227Inventory.cs file, 844InventoryDAL class type, 913InventoryDAL type, 811InventoryDALDisLayer class, 811–812, 814InventoryDataSet class, 826InventoryDataSet type, 832InventoryDataSet.Designer.cs file, 828InventoryDataSet.xsd file, 827InventoryDataTable class, 828InventoryRecord type, 912–913inventoryTable object, 791inventoryTable variable, 800InventoryTableAdapter type, 830Inventory.xml file, 862, 1112, 1114–1115Invoke( ) method, 1298InvokeMember( ) method, System.Type class, 529InvokeWebServiceActivity, WF, 921invTable object, 846IP address, 1163IPointy interface, 275IPointy-compatible objects, 281IRenderToMemory interface, 286is keyword, 211–212, 231, 277–278is-a relationship code example, 190, 192IsAbstract, System.Type class, 528IsAlive method, Thread type, 595IsArray, System.Type class, 528IsBackground method, Thread type, 595IsCancel property, 1069, 1114IsChecked property, 1070IsClass, System.Type class, 528IsClientConnected property, HttpResponse Type,

1198IsCOMObject, System.Type class, 528IsDbGenerated property, 848IsDefault property, 1069, 1114IsEnum, System.Type class, 528ISerializable interface, 222IService1.cs file, 901IService.cs file, 911IsGenericParameter, System.Type class, 528IsGenericTypeDefinition, System.Type class, 528IsHighlighted property, 1076IsInitiating property, 887IsInterface, System.Type class, 528IsMouseOver trigger, 1158IsNestedPrivate, System.Type class, 528IsNestedPublic, System.Type class, 528IsNull( ) method, 791IsNullable property, ADO.NET DbParameter, 767isolated storage

ClickOnce deployment, 707–708interacting with using storeadm.exe, 701issue of trust, 687locating, 700opening a store using IsolatedStorageFile

■INDEX 1351

Finditfasterathttp://superindex.apress.com

/

Page 70: Appendixes - Springer

creating custom directory structure, 706deleting user data from storage, 705–706overview, 702–704reading data from storage, 705writing data to storage, 704

overview, 687, 698–699scope of, 699System.IO.IsolatedStorage type, 702uses, 688

IsolatedStorage type, 702IsolatedStorageFile type, 702IsolatedStorageFile.GetStore( ) method, 703IsolatedStorageFile.GetUserStoreForAssembly( )

method, 704IsolatedStorageFilePermission attribute, 708IsolatedStorageFile.Remove( ) method, 705IsolatedStorageFileStream object, 704IsolatedStorageFileStream type, 704IsolatedStorageScope type, 702IsolatedStorageScope.User value, 705IsOneWay property, 887IsPostBack property in HTTP Request processing,

ASP.NET, 1198IsPostBack property, Page Type, 1195IsPressed property, 1069IsPressed trigger, 1158IsPrimaryKey property, 845, 848IsPrimitive, System.Type class, 528IsSealed, System.Type class, 528IsSecureConnection member, HttpRequest Type,

1196IsTerminating property, 887IsValueType, System.Type class, 528IsVersion property, 848ItemArray property, 789ItemCollection object, 1075<ItemGroup> element, 1024ItemHeight value, 1088Items property, 1229, 1248ItemsControl abstract base class, 1075ItemsSource attribute, 1114ItemsSource property, 1109ItemWidth value, 1088iteration, CIL, 642iterator methods

building with yield keyword, 292–293internal representation of, 294–295

ITypeInfo, IProvideClassInfo class interface, 1307IUnknown interface, 1292IUnknown, IDispatchEx class interface, 1307IValueConverter interface, 1106–1107

Jjagged array, 117javadoc utility, 176Java/J2EE language deficiencies, 4Jitter, just-in-time (JIT) compiler, 15Join( ) method, Thread type, 595

join operator, 466*.jpg file, 1129

Kkey frames, 1142Key property, 1149–1150, 1152keyboard events, window-level, 1020–1021KeyCode property, 978KeyDown event, 977KeyEventArgs parameter, 977KeyEventHandler delegate, 977/keyfile flag, 1297KeyUp event, 977Kill( ) method, System.Diagnostics.Process, 565

LLabel control, 1056Label object, 1140Label type, 817, 1102, 1137–1138, 1183Label widgets, 1058, 1065, 1200, 1210, 1212, 1246lambda expressions, 341, 374–381lambda operator (=>), 9language attribute, 1184language fundamentals

boxing and unboxing, 316custom namespaces, 475–476fully qualified type names, 476–478namespaces, default Visual Studio 2008, 480nested namespaces, 479–480static classes, 158static constructors, 157static data, 154–155static keyword, 152, 154–155, 157–158static methods, 153using aliases, 478–479

Language Integrated Query (LINQ), 433, 447langversion:linq option, 1318LastAccessTime property, FileSystemInfo class, 663LastChildFill attribute, 1092LastWriteTime property, FileSystemInfo class, 663late binding

description, 539invoking methods with no parameters, 540–541invoking methods with parameters, 541–542overview, 523System.Activator class, 540

layout managers, 1002LayoutMDI( ) method, 972LayoutTransform property, 1135lblOrder, Label type, 1229lblTextBoxText, Label widget, 1212lblTransparency button, 1139lblUserData Label type, 1276ldnull opcode, 249ldstr opcode, 92, CILlegacy types, 316Length, FileInfo class, System.IO, 669Length( ) method, Stream class, System.IO, 676

■INDEX1352

Page 71: Appendixes - Springer

Length property, 73, 119libmonogac subdirectory, 1319libraries, 1316LibraryBuild.rsp file, 1324life cycle of a web page, ASP.NET, 1200–1203lightweight events, 435LinearGradientBrush object, 1128LinearGradientBrush type, 1037, 1127, 1148LinearXXXKeyFrame type, 1142LineGeometry type, 1131LineJoin property, 1130LinqOverDataTable( ) method, 839/list option, 701<list> code comment, XML Elements, 177ListBox control, 1055, 1209, 1229, 1248ListBox type, 1078<ListBoxItem> type, 1075, 1077<ListBox.ItemTemplate> element, 1112ListDictionary member,

System.Collections.SpecializedNamespace, 316

ListMethods( ) method, 535List<T> array, 913List<T> member variable, 799, 995, 997List<T> type, 447, 456ListView object, 1112<ListView.View> element, 1114Load event, 972, 1198, 1201, 1276Load event handler, 830, 1249, 1261Load( ) method, 572, 575, 861LoadAsm( ) method, 690Loaded event, 1108, 1111LocalBuilder, System.Reflection.Emit namespace,

649LocalIntranet_Zone, 692LocalNullableVariables( ) method, 137locals directive, common intermediate language

(CIL), 640LocalVarDeclarations( ) method, 82Location property, 976location transparency, 868lock token and multithreaded applications,

604–607Lock( ), Unlock( ) methods, ASP.NET

HttpApplicationState members, 1255locking memory (unsafe), 409–410logical grouping, 1169logical resources, 1145long data type, 80lstColors ListBox object, 1079lstVideoGameConsole type, 1076lstVideoGameConsoles object, 1078Lutz Roeder’s Reflector for .NET development

tool, 65

MMac OS X Mono installer, 1319machine.config file, 522, 1184, 1272

MachineName property, 76MachineName, System.Diagnostics.Process, 564MagicEightBallServiceClient.exe file, 896, 900MagicEightBallService.cs file, 885MagicEightBallServiceHost.exe file, 899, 902MagicEightBallServiceLib namespace, 888MagicEightBallServiceLib.dll assembly, 888, 899/main option, 70MainForm type, 815MainForm.cs file, 798MainMenuStrip property, 960MainModule, System.Diagnostics.Process, 564maintaining session data, ASP.NET, 1263–1266MainWindow class, 959, 1014, 1108, 1111MainWindow, defining in XAML, 1022–1023MainWindow property, Application type, 1006MainWindow type, 958, 961, 976, 982, 992MainWindow_Paint( ) method, 988MainWindow.cs file, 963, 973, 979, 991MainWindow.Designer.cs file, 963MainWindow.g.cs file, 1024MainWindowHandle, System.Diagnostics.Process,

564MainWindowTitle, System.Diagnostics.Process,

564MainWindow.xaml.cs file, 1029managed code, 8–9, 1283managed heap, 246–252manifest, assemblies, 481MapPath( ) method, 1196mapping C# types to CIL types, 635mapping parameters to variables, CIL, 641Margin control, 1094Margin value, 1114MarkedAsDeletable( ) method, 802master constructor, 150*.master file, 1216, 1218, 1222master pages, 1178, 1216–1222MasterPageFile attribute, 1184, 1223MasterPageFile property, Page Type, 1195MasterPage.master file, 1217MathOperation property, 937MathService.cs file, 901MathServiceLibrary namespace, 901MathServiceLibrary.dll assembly, 904MathWinService.cs file, 904MatrixTransform type, 1135MaximizeBox property, 979MaximumSize member, 703maxstack directive, CIL, 640MaxValue property, 84mcs/gmcs compilers, 1321MDIChildActive event, 972Me keyword

chaining constructor calls using, 149–151observing constructor flow, 151–152, 175overview, 147–149

MediaCommands object, 1100

■INDEX 1353

Finditfasterathttp://superindex.apress.com

/

Page 72: Appendixes - Springer

MediaElement control, 1056member shadowing, 208–210member variables, 141MemberInfo class, System.Reflection namespace,

528MemberwiseClone( ) method, Object Class, 213memory allocation (unsafe), 409–410memory management

in CIL, 247–248Finalize( ) vs. IDisposable interface, 262–263first rule, 246fourth rule, 260resource wrapper code example, 262–263second rule, 248third rule, 256

MemoryStream type, input/output, System.IO, 662Menu (or TreeView) widget, 1219Menu control, 1056, 1218, 1220Menu property, 971Menu type, 1220<Menu> definition, 1096MenuEventArgs parameter, 1221MenuItem object, 1094MenuItemClick event, 1221MenuStrip control, 965MenuStrip object, 960MenuStrip type, 959Merge( ) method, 786Message property, 98, 222, 234Message Transmission Optimization Mechanism

(MTOM), 882MessageBox type, 1012, 1067MessageBox.Show( ) method, 974, 1082metadata, 524, 530–535, 891, 894, 1292, 1316method attribute, 1195method group conversions, C# 2.0, 372–373method parameters, CIL, 638Method property,

System.MulticastDelegate/SystemDelegate, 345

method scope, 148MethodBuilder, System.Reflection.Emit

namespace, 649MethodInfo class, System.Reflection namespace,

528methods

CIL, 637hidings, 208overloading, 107overriding, 199

Microsoft C# command-line compiler, 1321Microsoft Express IDEs, overview, 50Microsoft Foundation Classes (MFC), 1284Microsoft Message Queuing (MSMQ), 869Microsoft recommended event pattern, 367–368Microsoft Transaction Server (MTS), 869Microsoft.CSharp.Targets file, 1024Microsoft.WinFX.targets file, 1024

midl.exe compiler, 1292MIInterfaceHierarchy project, 289milcore.dll binary, 1010MinimizeBox property, 979MinimumCapacity member, 793MinValue property, 84mnemonics, 619–620, CILmnuFileExit type, 960mnuFileExit_Click( ) method, 960mode attribute, 1270Modified value, 791ModifierKeys property, 969Modifiers property, 978Module class, System.Reflection namespace, 528module directive, common intermediate language

(CIL), 630module set for a process example code, 569ModuleBuilder type, 653–654Monitor type, System.Threading Namespace, 594mono print, 1322mono runtime utility, 1330monodis utility, 1322, 1325monop/monop2 tool, 1322mouse events, window-level, 1020MouseButtons enumeration, 976MouseButtons property, 969MouseDown event, 970, 993MouseDown event handler, 995, 1066MouseEnter event, 970, 1094, 1126MouseEventArgs class, 976MouseEventArgs type, 961MouseExit event, 1094MouseHover event, 970MouseLeave event, 970MouseMove event, 970, 975, 1208MouseOverStyle property, 1154MouseUp event, 970, 976MouseWheel event, 970MoveTo( ) method

DirectoryInfo class, 664FileInfo class, 669

mresources directive, CIL, 630msbuild.exe utility, 1023–1024mscoree.dll, 22mscorlib.dl, 22, 1077, 1323MSMQ-centric bindings, 884MsmqIntegrationBinding binding, 883multicast delegate call, 344–345multicasting, delegates, 351–353multidimensional arrays, 119multifile assemblies, 12, 484–485, 496–498multiple document interface (MDI) application,

968multiple exceptions, 236–237multiple inheritance, 187, 287–289multiple result sets, DbDataReader object,

ADO.NET, 762multiple sort orders (IComparer), 302–303

■INDEX1354

Page 73: Appendixes - Springer

multithreaded applicationsAsyncCallback delegate, 591–592asynchronous operations, 587–589AsyncResult class, 592atomic operations, 585BeginInvoke( ), 587–588, 591–593CLR thread pool, 610, 612concurrency, 584, 602–605delegate review, 585, 587EndInvoke( ), 587–588execution speed vs. responsiveness, 600foreground vs. background threads, 601–602lock keyword and synchronization, 604–607Main( ) method, 592overview, 583secondary thread creation, 597–598state data, 592–593synchronization, 584–585, 587, 589–590, 608System.Threading Namespace, 593System.Threading.Interlocked type and

synchronization, 607–608Thread class, 583thread relationship to process, AppDomain, and

context, 583–585thread-volatile operations, 584Timer callbacks, 609–610

<MultiTrigger> element, 1153MustInherit keyword, 203–204, 207MustOverride, 204–208mutator method, 164Mutex type, System.Threading Namespace, 594My_Computer code group, 696My_Computer_Zone, 692, 698MyApp.g.cs file, 1027, 1030MyApp.xaml.cs file, 1030MyBase, controlling base class creation with,

192–194MyData.txt file, 704, 706MyDoubleConverter type, 1107MyExtensionMethods class, 430MyExtensions class, 425, 430MyExtensions.cs file, 430MyExtensionsLibrary namespace, 431MyExtensionsLibrary.dll file, 431myInt type, 416MyPaintProgram namespace, 992MyPoint type, 130MyPrivateQ private queue, 884myProxy.cs file, 897myShapes array, 208myString type, 416MyWPFApp class, 1012

N\n character, 89n string, 78Name attribute, 1059, 1171, 1274name clashes, 283–284

name field, 147Name, FileInfo class, System.IO, 669Name method, Thread type, 595–596Name property, 663, 847, 926named iterators, 293–294NameLength dictionary, 932NameNotValid method, 929_NameOfTheClass interface, 1295namespace directive, common intermediate

language (CIL), 630namespace keyword, 475–476/namespace option, 849namespaces

default Visual Studio 2008, 480examples in C#, VB.NET, C++, 24–25fully qualified names, 27overview, 23–24primary .NET namespaces, 25programmatic access, 26–28role of Microsoft namespaces, 26

<namespaces> element, web.config File, 1204NameValueCollection member,

System.Collections.SpecializedNamespace, 316

Nant development tool, 65narrowing operation, 96NarrowingAttempt( ) method, 97NavigationCommands object, 1100NDoc development tool, 65, 180nested namespaces, 479–480nested panels, 1108nested types

and access modifiers, 164definitions, 197–199

.NET attributes, 951

.NET Frameworkbase class libraries, 7basic building blocks overview, 6Common Language Infrastructure(CLI), 32–33common language runtime (CLR) overview, 6Common Language Specification (CLS)

overview, 6Common Type System (CTS) overview, 6core features, 6ECMA standardization, 32interoperability with COM, 6Mono, 33.NET-aware programming languages, 9–11non-Windows platforms, 32–33overview, 6Portable .NET, 33as radical change, 6Virtual Execution System (VES), 32

.NET Framework Configuration utility, 502–504,515

.NET System data type, 1290

.NET type metadata, 15–16netmodule file extension, 485, 496–497

■INDEX 1355

Finditfasterathttp://superindex.apress.com

/

Page 74: Appendixes - Springer

NetMsmqBinding binding, 883NetNamedPipeBinding class, 883–884NetPeerTcpBinding class, 883netTcpBinding binding type, 899NetTcpBinding class, 883, 900<netTcpBinding> subelement, 900new keyword, 82, 93, 128, 142

allocating objects with, 143–144CIL implementation, 247references, 246

New Project dialog box, Visual Studio 2008, 53NewFunkyStyle style, 1150NewLine property, 76NewLine, TextWriter, System.IO, 678newobj CIL instruction, 247noautoinherit, 626, CIL compiler flagsnonabstract .NET types, 1021None value, ClassInterfaceType enumeration, 1308non-Shared data, 154NoResize attribute, 1113Notepad, building .NET applications using, 46–47NotImplementedException objects, 435NotInheritable keyword, 188, 195, 202NotOverridable keyword, 202–203null, setting object references to, 248–249nullable data type, 136Nullable<T> property, 137NullReferenceException, delegates, 350–351Nunit development tool, 65

OObject class, 212object contexts

boundaries, 577context 0, 577context-agile, 578–579context-bound, 578–579overview, 561program example, 579–581

object data type, 81object generations, 251–252object graph

definition, 712garbage collection, 249–250reachable objects, 249–250relationships, 713simple example, 712

object initializer syntax, 436_Object interface, 1311object keyword, boxing, 316object lifetime

object generations, 251–252overview, 245System.GC, 252when heap objects are removed, 246–248

object reference type, 81object resources, 1145ObjectIDGenerator, serialization, 724

objectsdifferences from classes and references, 245setting references to null, 248–249

ObservableCollection<T> type, 1110, 1115Obsolete attribute, 543–544ObtainAnswerToQuestion( ) method, 887, 902OfType<T>( ) method, 458OLE View utility, 1294oleautomation data type, 1283on operator, 466On prefix, 435onclick attribute, 1173, 1182, 1188onclick event, 1173OneWay value, 1105OnPetNameChanged( ) method, 851OnPetNameChanging( ) method, 851OnRender( ) method, 1122OnStart( ) method, 904OnStop( ) method, 904Opacity property, 970, 1128opcodes, 619, 638–640OpCodes, System.Reflection.Emit namespace, 649OpenFileDialog type, 997OpenRead( ) method, FileInfo class, System.IO,

669, 671OpenText( ) method, FileInfo class, System.IO, 669,

672OpenTimeout property, 892OpenWrite( ) method, FileInfo class, System.IO,

669, 671–672Operation property, 940[OperationContract] attribute, 880, 885, 897, 912operator constraints, lack of with generics,

336–337operator overloading

binary operators, 389–391C# to CIL special names index, 395cautions, 396CIL internal code, 394, 396comparison operators, 394description, 388equality operators, 393overview, 383shorthand assignment operators, 392unary operators, 392–393

Operator property, 1233OrderAutoDialog class, 982, 985OrderAutoDialog type, 984OrderAutoDialog.cs file, 979OrderAutoDialog.Designer.cs file, 983OrderBy( ) method, 461orderby operator, 463, 468OrderBy<T, K>( ) method, 461OrderedEnumerable type, 451, 461Ordinal property, 787Orientation property, 1088Original value, 792OtherKey named property, 851

■INDEX1356

Page 75: Appendixes - Springer

/out: flag, 896, 1321out keyword, 107out modifier, 109out parameter, 108[out, retval] attributes, 1296[Out] attribute, System.Runtime.InteropServices,

1306outer variables, 371–372outerEllipse Ellipse type, 1067outerEllipse object, 1066output parameters, 109–110Output property, HttpResponse Type, 1199OutputStream property, HttpResponse Type, 1199overloading

methods, 107, 146, 386operators

binary operators, 389–391C# to CIL special names index, 395cautions, 396CIL internal code, 394–396comparison operators, 394description, 388equality operators, 393overview, 383shorthand assignment operators, 392unary operators, 392–393

overridable and overrides keywords, 199–201Overridable keyword, 199, 205Overrides keyword, 199, 209overriding, 201–202

PPadding property, 1093PadLeft( ) method, 87PadRight( ) method, 87Page events, ASP.NET, 1201Page member, System.Web.UI.Control, 1210Page object, 1246Page parent class, 1194Page property, System.Web.UI.Control in ASP.NET,

1210Page type, 1163, 1198Page_Load( ) event, 1210Page_PreInit event, 1242<Page> declaration, 1032<pages> element, 1239Paint event, 970, 993, 1118PaintEventArgs type, 961, 988PaintEventHandler delegate, 988Panel control, 1056Panel type, 1008, 1210panels, nested, 1108ParallelActivity, WF, 921<param> elements, 177–178parameter arrays, 111Parameter object, ADO.NET data providers, 734ParameterBuilder, System.Reflection.Emit

namespace, 649

ParameterInfo class, System.Reflectionnamespace, 528

parameterized command objects, ADO.NET,766–767

ParameterizedThreadStart delegate,System.Threading Namespace, 594,597–598, 600–601

ParameterName property, ADO.NET DbParameter,767

Parameters, DbCommand, ADO.NET, 760<paramref> code comment, XML Elements, 177params keyword, 107, 111params parameter, 108parent class, specifying, 186–187Parent member, System.Web.UI.Control, 1210Parent property, DirectoryInfo class, 664ParentRelations member, 793Parse( ) method, 861ParseFromStrings( ) method, 86partial keyword, 8, 433, 435Partial methods, 433partial modifier, 434partial types, 175–176/password option, 848Password property, 1082PasswordBox type, 1081–1082PasswordChar property, 1082Path type, input/output, System.IO, 662Path value, 1103PathGeometry type, 1131Peek( ) method, TextReader, System.IO, 679PeekChar( ) method, BinaryReader class, 682Pen type, 987, 989, 1130Pens type, 987permission set, 688Permission Set tab, 694permission sets, role of in code access security, 695<permission> code comment, XML Elements, 177persistence of cookies, ASP.NET, 1267Persistence services, WF, 920persistent cookie, 1267Person class, 133Person variable, 214peverify.exe tool, 629PictureBox control, 985platform invocation, 1284Platform Invocation Services (PInvoke), 6platform-independent, 1315Point definition, 129Point structure, 126Point type, 436, 438Point variable, 127pointer types and operators

& operator, 407* operator, 407> operator, 408–409example, swap function, 407field access, 408–409table of operators, 404

■INDEX 1357

Finditfasterathttp://superindex.apress.com

/

Page 76: Appendixes - Springer

PointRef type, 130polymorphic interface, 162, 185, 204, 208, 271,

1194polymorphic support

abstract classes and MustInherit keyword,203–204

building polymorphic interface withMustOverride, 204–208

member shadowing, 208–210NotOverridable keyword, 202–203overridable and overrides keywords, 199–201overriding with Visual Studio 2005, 201–202overview, 199

polymorphism, 160, 162–163, 207abstract classes, 203–204abstract methods, 204–208method hiding, 208override keyword, 199overview, 199virtual keyword, 199

<portType> elements, 886postbacks, 1172PreInit event, 1201, 1242preprocessor directives

#define, 411, 413–414#elif, 411–413#else, 411–413#endif, 411–413#endregion, 411#if, 411–413#region, 411#undef, 411, 413–414description, 411overview, 383

PreRender event, Page type, 1201PresentationCore.dll assembly, WPF, 1005PresentationCore.dll file, 1137PresentationFoundation.dll assembly, WPF, 1005Preview prefixed tunneling event, 1068PreviewMouseDown event fires, 1067primary thread, 562PrimaryKey member, 793PrimaryKey property, 793Print( ) method, 286PrintAllPetNames( ) method, 863PrintArray( ) method, 118PrintDataSet( ) method, 793, 795, 801, 810PrintMessage( ) method, 621PrintTable( ) method, 796Priority method, Thread type, 595, 597PriorityBoostEnabled, System.Diagnostics.Process,

565PriorityClass, System.Diagnostics.Process, 565PriorityLevel, ProcessThread type, 568Private access keyword, 166Private access modifier, 163private assemblies

configuration, 500description, 499

identity, 499probing, 499–500

private data, 127, 165probing, private assemblies, 499–500Process class, System.Diagnostics namespace, 564process identifier (PID), 561, 565–567ProcessCreditRisk( ) method, 780processes

module set example code, 569overview, 561process manipulation example code, 565–566starting and stopping example code, 570–571System.Diagnostics namespace, 563thread examination example code, 566–567

ProcessExit event, System.AppDomain, 573,576–577

ProcessModule type, System.Diagnosticsnamespace, 564

ProcessModuleCollection, System.Diagnosticsnamespace, 564

ProcessName, System.Diagnostics.Process, 565ProcessorAffinity, ProcessThread type, 568ProcessStartInfo, System.Diagnostics namespace,

564ProcessThread, System.Diagnostics namespace,

564ProcessThread type, 568ProcessThreadCollection, System.Diagnostics

namespace, 564ProcessUsernameWorkflow class, 929, 933ProcessUsernameWorkflow.cs file, 926production-level class definition, 165Profile property, 1273–1274, 1279<profile> element, 1273Profile.Address, 1278ProfileCommon type, 1279Program class, 75, 77, 81, 108, 450, 452, 459, 462,

856, 859Program type, 690, 852, 1326Program.cs file, 930programmatic identifier (ProgID), 1284ProgressBar control, 1056projectless manner, 1190properties, 167, 169–170, 637Properties property, Application type, 1006Properties window, 927, 967Property keyword, 167PropertyBuilder, System.Reflection.Emit

namespace, 649PropertyChanged event, 850PropertyChangedEventArgs namespace, 850PropertyChangedEventHandler namespace, 850PropertyChanging event, 850PropertyCollection object, 785<PropertyGroup> element, 1024PropertyInfo class, System.Reflection namespace,

528Proposed value, 792Protected access modifier, 163

■INDEX1358

Page 77: Appendixes - Springer

protected data, 194Protected field data, 195Protected Friend access modifier, 163protected keyword, 194–195Protected subroutines, 195ProtectionLevel property, 887Provider attribute, Profile Data, 1274provider factory model, ADO.NET, 749–751Public access modifier, 142, 163public keyword, 127, 199, 983public methods, 194public properties, 194public property, 127PublicNotCreatable property, 1300Publish Wizard button, 709Publisher certificate, 689publisher policy assemblies, 518–519publish.htm file, 709push and pop, 620–621, CIL

Qquery expressions, 420, 447–448query operators, 447–448, 451QueryInterface( ) method, 1305QueryOverInts( ) method, 454QueryOverStrings( ) method, 450–451QueryString member, HttpRequest Type, 1196QueryString( ) method, 1176QueryString property, 1197QueryStringsWithAnonymousMethods( ) function,

461QueryStringsWithEnumerableAndLambdas( )

method, 462QueryStringsWithOperators( ) method, 459, 462QueryStringsWithSequenceAndLambdas( )

method, 460question mark symbol (?), 137Queue System.Collections class type, 312, 314–315Queued Components (QC), 869queuing data, 869

R\r character, 89RadialGradientBrush object, 1128RadialGradientBrush type, 1127RadioButton control, 1056RadioButton object, 992radioButtonCircle object, 992radioButtonRect object, 992RadiusX property, 1125RadiusY property, 1125RangeValidator control, ASP.NET, 1231, 1233Rank property, 119RawUrl member, HttpRequest Type, 1196reachable objects, 246Read( ) method, 676, 679, 682, 795ReadAllBytes( ) method, 674ReadAllLines( ) method, 674

ReadAllText( ) method, 674ReadBlock( ) method, TextReader, System.IO, 679reading cookies, ASP.NET, 1268–1269reading from a text file, 679ReadLine( ) method, TextReader, System.IO, 679readOnly attribute, Profile Data, 1274read-only class properties, 171read-only fields, 174–175ReadOnly keyword, 165, 171ReadOnly property, 171, 787ReadToEnd( ) method, TextReader, System.IO, 679ReadXml( ) method, 796ReadXmlSchema( ) method, 796Rect variable, 1123Rectangle class, 438Rectangle element, 1090Rectangle type, 132, 1125<Rectangle> element, 1120, 1136<RectangleGeometry> type, 1131–1132rectangular array, 117rectWidth members, 1123Redirect( ) method, 1199redirecting users, ASP.NET, 1200ref keyword, 107, 111ref parameter, 108, 110/reference: flag, 1321reference parameters, 110reference types, 107, 316references, 444

differences from classes and objects, 245memory management using, 246–247new keyword, 246

reflection, 527Reflector tool, 31reflector.exe file, 1146ReflectOverQueryResults( ) method, 451RefreshGrid( ) function, 1262regasm.exe command-line tool, 1310#region, preprocessor directive, 411Region type, 987Register( ) method, 1062registered data provider factories, ADO.NET,

750–751registration of events, 365–367RegularExpressionValidator control, ASP.NET,

1231, 1233RejectChanges( ) method, 786, 802Relations property, 785relaxed delegates. See covarianceRelease( ) method, 247, 1291, 1305–1306<remarks> code comment, XML Elements, 177RemotingFormat member, 793RemotingFormat property, 785, 797Remove( ) method, 87, 345, 704, 856, 864, 1255,

1257, 1266RemoveAll( ) method, 1255, 1257, 1266RemoveAt( ) method, 1255RenderOpen( ) method, 1122

■INDEX 1359

Finditfasterathttp://superindex.apress.com

/

Page 78: Appendixes - Springer

RenderTransform property, 1135RenderTransformOrigin property, 1135, 1144RepeatBehavior property, 1138, 1140RepeatButton control, 1056RepeatButton type, 1071Replace( ) method, 87Request object, 1176, 1196Request property, 1195, 1253request states, 923Request.Form collection, 1176Request.QueryString( ) method, 1176request/response cycle, HTTP, 1163RequestType member, HttpRequest Type, 1196RequiredFieldValidator control, ASP.NET,

1231–1232ResizeMode attribute, 1113resource dictionary, 1149ResourceResolve event, System.AppDomain, 573Response objects, 1176Response property, 1195, 1198, 1253Response.Cookies property, 1267Result property, 928Resume( ) method, Thread type, 595retained mode graphics, 1117return value, interface used as, 280–281[return] attribute, 852<returns> code comment, XML Elements, 177Reverse( ) method, 119ReverseDigits( ) method, 425–426Reverse<T>( ) method, 468rich controls, 1213RichTextBox control, 1056RichTextBox property, 1083Root property, DirectoryInfo class, 664RotateTransform object, 1144RotateTransform type, 1135–1136roundButtonTemplate template, 1156round-trip engineering, 621, 623–626routed events, 1065RoutedEventArgs type, 1066RoutedEventHandler delegate, 1014, 1064RoutedUICommand type, 1099<RowDefinition> element, 1090RowError property, 789RowPostPaint event, 808RowState property, 789, 791, 793Run( ) method, System.Window.Application, 1006runat="server" attribute, 1185, 1238runtime, 22, 174, 919Runtime Callable Wrapper (RCW), 1283, 1287, 1289RunWorkerAsync( ) method, 614RunWorkerCompleted event, 614RunWorkerCompletedEventArgs.Result property,

615

SSAFEARRAY COM type, 1303SaveAs( ) method, 1196

SaveAsBinaryFormat( ) method, 718SaveFileDialog type, 996–997saving CIL code using ildasm.exe, 621, 623–624SavingsAccount class, 154, 157sbyte data type, 80<ScaleTransform> type, 1135–1136Scheduling services, WF, 920Scope member, 703<script> block, 1185, 1192, 1201, 1207, 1251scripting languages, 1173ScrollableControl class, 971ScrollBar control, 1056, 1103ScrollBar type, 1007, 1106<ScrollBar> type, 1103<ScrollViewer> type, 1093sealed classes, 195–196, 202sealing, 188security policy, 688<see> code comment, XML Elements, 177<seealso> code comment, XML Elements, 177Seek( ) method

BinaryWriter class, 682Stream class, 676

Select( ) method, 461, 803, 819select operator, 463, 465select statement, 467SelectCommand member, 808SelectCommand property, 809SelectedIndex object, 1079SelectedIndex property, 1078SelectedItem property, 1078, 1115SelectedShape.Circle variable, 993SelectedShape.Rectangle variable, 993SelectedValue property, 1078SelectionChanged event, 1109, 1154SelectionChanged handler, 1112Semaphore type, System.Threading Namespace,

594SendAPersonByValue( ) method, 134<Separator> element, 1095SequenceActivity, WF, 921Sequence.Where<T>( ) method, 460Sequential Workflow console application, 918, 926Sequential Workflow Library project, 946SequentialWorkflowActivity type, 926<Serializable> attribute, 1272, 1278serialization

BinaryFormatter object graph contents, 725collections, 723–724customizing using attributes, 728–729customizing using ISerializable, 726–727definition, 711GetObjectData( ) method, 726–727IFormatter interface, 716object graph, 712ObjectIDGenerator, 724overview, 711persisting user preferences example, 712

■INDEX1360

Page 79: Appendixes - Springer

public and private fields, public properties, 714Serializable attribute, 713type fidelity, 717

[Serialization] attribute, 996SerializationFormat.Binary file, 797serializeAs attribute, 1274, 1278Serialized attribute, 543server controls in ASP.NET, 1207–1209/server option, 848Server property, 1195, 1203, 1253server-side script, 1175ServerVariables member, HttpRequest Type, 1196service behavior, 894service contracts, 880service types, 880<service> element, 889, 894Service1.cs file, 904[ServiceContract] attribute, 880, 885ServiceContractAttribute type, 886serviced component, 869ServiceHost type, 879serviceHostingEnvironment subelement, 894service-oriented architecture (SOA), 874ServiceReference namespace, 898services subelement, 894<services> element, 889Service.svc file, 914session cookies, ASP.NET, 1267session data, ASP.NET, 1263–1266Session property, 1195, 1247, 1253session variable, 1247Session_End( ) event handler, 1253, 1263Session_Start( ) event handler, 1252, 1263SessionID property, 1266SessionMode property, 887sessionState element, Web.config, ASP.NET, 1204,

1269–1270<sessionState> element, 1204, 1269–1271Set scope, 167set_SocialSecurityNumber( ) method, 170SetDriverName( ) method, 147SetF1CommandBinding( ) method, 1101SetLength( ) method, Stream class, System.IO, 676<Setter> element, 1148, 1152–1153, 1159setup.exe application, 709SetValue( ) method, 1063shadowing, 208Shadows keyword, 209shallow copy, cloneable objects, 295–298Shape base class, 208, 1125Shape type, 162, 205, 1119, 1124ShapeData namespace, 992ShapeData type, 995ShapeData.cs file, 992Shape-derived types, 1119–1120ShapeInfo member variable, 132ShapePickerDialog class, 993*.shapes files, 997

shared constructor, 158Shared field data, 154Shared keyword

overview, 152–153Shared constructors, 157–158Shared data, 154–156Shared methods (and fields), 153–154

shared members, 152Shared method, 155Shared properties, 171–172SharpDevelop, 48–50Shift property, 978shopping cart application, ASP.NET, 1264–1266ShoppingCart class, 1272short data type, 80short variables, 95Show( ) method, 971, 982, 1012Show Visual Tree button, 1032ShowDialog( ) method, 972, 982ShowEnvironmentDetails( ) method, 75ShowInstructions method, 927ShowInTaskbar property, 971, 979ShowMessageBox property, 1235ShowSummary property, 1235Shutdown( ) method, 1014Silverlight, 1004simple controls, 1213SimpleArrays( ) method, 114SimpleComServer, 1284–1285, 1294SimpleCSharpApp, 69SimpleInventory.xml file, 860SimpleLine object, 1126SimpleVSWinFormsApp, 961SimpleWFApp.cs file, 957SimpleXamlApp.csproj file, 1024SimpleXamlApp.exe program, 1142SimpleXamlPad.exe application, 1048–1052, 1153single file code model, ASP.NET, 1179single logical parameter, 111single-file assemblies, 12single-file page model, 1179SinglePageModel, 1192single-threaded apartment, 965sink object, callback interfaces, 305, 307–308*.sitemap file, 1219SiteMapDataSource component, 1220<siteMapNode> element, 1219SiteMapPath type, 1221SiteMapPath widget, 1226Size property, ADO.NET DbParameter, 767sizeof keyword, 410SkewTransform object, 1136* skin files, 1238–1239SkinID member, System.Web.UI.Control, 1210SkinID property, 1210, 1240Sleep( ) method, Thread type, 594Slider control, 1056sn utility, 1322

■INDEX 1361

Finditfasterathttp://superindex.apress.com

/

Page 80: Appendixes - Springer

sn.exe, strong name utility, 505–507*.snk file, 1297, 1310, 1324SoapFormatter, serialization, 719SoapFormatter type, 714, 717Social Security number (SSN), 92SocialSecurityNumber property, 169SolidColorBrush object, 1127SolidColorBrush type, 1107, 1127<SolidColorBrush> element, 1128Solution Explorer, 53, 926Sort( ) method, 119SortedList System.Collections class type, 312sorting and paging example, ASP.NET, 1227SoundPlayerAction control, 1056Source attribute, 1114Source property, 1132, 1145SpeedRatio property, 1138SpeedUp( ) subroutine name, 142SpellCheck.IsEnabled property, 1081SpellingError object, 1082SpinButtonWithLinearKeyFrames.xaml file, 1144Split( ) method, 87/sprocs option, 848SqlCommand object, 812, 830, 853SqlCommand type, 812, 843SqlCommandBuilder property, 812SqlConnection type, 843SqlConnectionStringBuilder type, 846SqlDataAdapter member variable, 811SqlDataAdapter object, 813SqlDataAdapter type, 834, 843SqlDataSource type, 1224sqlmetal.exe utility, 848, 850–851, 855sqlmetal.exe-generated code, 852SqlParameter object, 830SqlParameter type, 812SqlProfileProvider, 1273square brackets ([ ]), 215, 1295Stack System.Collections class type, 312, 315stackalloc keyword, 409–410stack-based programming, 620–621StackPanel control, 1056, 1065StackPanel objects, 1079StackPanel panel control, 1085<StackPanel> element, 1071, 1082, 1104, 1111StackTrace property, 76, 222, 228StartAddress, ProcessThread type, 568StartLineCap controls, 1130StartPosition property, 972StartType property, 907Startup event handler, 1013StartupEventArgs delegate, 1012StartupEventArgs parameter, 1015StartupEventHandler delegate, 1012StartupLocation.CenterScreen value, 1027StartupUrl property, 1006, 1023, 1026state data, multithreaded applications, 592–593state machine workflows, 923

state management techniquesapplication cache, 1259application level state data, 1255application shutdown, 1258applications vs. sessions, 1254ASP.NET profile API

accessing profile data programmatically,1274–1277

ASPNETDB database, 1272–1273defining user profile within web.config,

1273–1274grouping profile data and persisting custom

objects, 1277–1279overview, 1272

control state, state management, 1251cookies creation, 1267cookies overview, 1267custom view states, state management, 1250data caching, 1259–1263Global.asax file, 1251–1253HttpApplication type overview, 1245HttpSessionState members, 1266maintaining session data, 1263–1266modifying application data, 1257–1258overview, 1245per user data stores, 1263–1266persistence of cookies, 1267problems in state management, 1245–1247reading cookies, 1268–1269role of <sessionState> element, 1269–1271session cookies, 1267session data, 1263–1266view state, 1248–1250Web.config, 1269–1270

State property, 757, 892StateBag type, 1250stateConnectionString attribute, 1270stateless wire protocol, 1164, 1245[STAThread] attribute, 965static assemblies, 648static classes, 171, 424, 429static keyword, 70, 152, 154–155, 157–158StaticResource markup extension, 1107, 1149, 1152StatusBar control, 1056StatusBar type, 1096StatusCode property, HttpResponse Type, 1199StatusDescription property, HttpResponse Type,

1199storeadm.exe utility, 701stored procedures using DbCommand, ADO.NET,

768Storeyboard.TargetName value, 1143<Storyboard> element, 1141Storyboard.TargetProperty value, 1143Stream class, System.IO, 675–676StreamReader, StreamWriter, 677, 680Stretch property, 1125String class, 217

■INDEX1362

Page 81: Appendixes - Springer

string data type, 81, 87, 141string keyword, 85String parameter, 193string variable, 87, 811, 1300<StringAnimationUsingKeyFrames> element, 1143StringAreImmutable( ) method, 92StringBuilder class, 93String.Concat( ) method, 88StringDictionary member,

System.Collections.SpecializedNamespace, 316

StringEnumerator member,System.Collections.SpecializedNamespace, 316

String.Format( ) method, 79StringFormat type, 987String.Length property, 103StringReader, StringWriter, System.IO, 680StringWriter, StringReader types, input/output,

System.IO, 662Stroke property, 1125StrokeDashArray property, 1125StrokeEndLineCap property, 1125StrokeThickness property, 1125strong names of assemblies, 481, 490, 505–508struct keyword, 126structure types, 18structured exception handling

advantages, 221application-level exceptions, 231, 233–234bugs, description, 219catching exceptions, 225–226configuring exception state, 226custom exceptions, 231, 233–234entities used in, 221exceptions, description, 219finally block, 239–240generic exceptions, 224, 238inner exceptions, 239keywords used, 221multiple exceptions, 236–237overview, 219possible .NET exceptions, 240rethrowing exceptions, 238simple example, 222, 224–226System.Exception, 221–222, 224–226system-level exceptions, 230–231System.Serializable attribute, 235template, exception, 235throwing an exception, 224–225traditional exception handling, 220try/catch block, 225–226typed exceptions, 241unhandled exceptions, 241user errors, description, 219Visual Studio 2005 features, 240, 242–243

structures, common intermediate language (CIL),632–633

style sheets, 1237<Style> element, 1148StyleWithTriggers.xaml file, 1153subclasses, 206subject matter experts (SMEs), 918Submit button, 1174, 1234SubmitChanges( ) method, 856submitting form data, ASP.NET, 1174–1175subroutines and functions, defining, 111subset data type, 420subset variable, 451–452subsystem directive, common intermediate

language (CIL), 630Subtract( ) method, 432, 1288, 1308Suggestions property, 1082sum keyword, 97<summary> code comment, XML Elements, 177SuppressContent property, HttpResponse Type,

1199Suspend( ) method, Thread type, 595SuspendActivity, WF, 921*.svc file, 878, 915SvcConfigEditor.exe utility, 883, 902svcutil.exe tool, 894, 896–897SyncDelegateReview program, 586Synchronization attribute, 579, 608synchronizing threads, 589–590synchronous delegate call, 342Sysem.Windows.Shapes.Shape namespace, 1119System namespace, 70, 80–81, 94, 100, 125, 459,

1184System.Activator class, late binding, 540System.AppDomain class

AssemblyLoad event, 573AssemblyResolve event, 573BaseDirectory( ), 572CreateDomain( ), 572, 574CreateInstance( ), 572DomainUnload event, 573ExecuteAssembly( ), 572GetAssemblies( ), 572GetCurrentThreadId( ), 572Load( ), 572, 575ProcessExit event, 573ResourceResolve event, 573TypeResolve event, 573UnhandledException event, 573Unload( ), 572, 576–577

System.ApplicationException, structuredexception handling, 231, 233–234

System.Array class, 73, 107, 111, 119, 450, 454, 471,1303

System.Boolean data type, 85, 136System.Boolean structure, 82System.Char type, 86System.Collection.ArrayList, indexer methods, 384System.Collections, 458

■INDEX 1363

Finditfasterathttp://superindex.apress.com

/

Page 82: Appendixes - Springer

System.Collections class types, 312ArrayList, 312–313Hashtable, 312Queue, 312, 314–315SortedList, 312Stack, 312, 315

System.Collections interfaces, 310–311System.Collections namespace, 305, 320, 690System.Collections.ArrayList, 1278System.Collections.Generic namespace, 309, 316,

456System.Collections.Generic.EqualityComparer<T>

type, 443System.Collections.Generic.List<>, 324–326System.Collections.ObjectModel namespace, 1110System.Collections.Specialized.ListDictionary,

indexer methods, 386System.ComponentModel namespace, 850, 973System.ComponentModel.Component class, 968System.Configuration namespace, 521System.Configuration.dll file, 816System.Console class, 76, 78System.ContextBoundObject, 578–579System.Core namespace, 846System.Core.dll assembly, 449, 451, 459, 837, 840System.Data, ADO.NET, 737System.Data namespace, 783, 809, 839System.Data.Common namespace, 810System.Data.Common.DataTableMapping type,

810System.Data.DataSetExtensions.dll assembly, 449,

837, 839–840System.Data.DLinq.dll assembly, 449System.Data.Extensions.dll assembly, 449System.Data.Linq namespace, 844, 846System.Data.Linq.dll assembly, 449, 837, 844, 849,

854System.Data.Linq.Mapping namespace, 843–844System.Data.SqlClient namespace, 809, 1182System.Delegate base class, 344–345System.Diagnostics namespace, 564System.Diagnostics.Process, 564–565System.Diagnostics.Process.ExitCode property, 71SystemDirectory property, 76System.Drawing namespace, 986, 992System.Drawing.dll, 985, 999System.Drawing.Drawing2D namespace, 986, 989System.Drawing.Graphics class, GDI+, 987System.Drawing.Imaging namespace, 986System.Drawing.Printing namespace, 986System.Drawing.Text namespace, 986System.EnterpriseServices namespace, 869System.Enum class, 123–124System.Environment class, 75System.Environment type, 74–75System.EventArgs argument, 932, 960System.EventHandler, 932, 960, 1185

System.Exception, 1253Data property, 222, 229–230HelpLink property, 222, 228–229InnerException property, 222Message property, 222, 234StackTrace property, 222, 228TargetSite property, 222, 227

System.GC, 252–255System.Guid, 297–299, 786System.IdentityModel.dll assembly, 876System.Int32 data type, 129System.Int32 enumeration, 121System.Int32 type, 426, 431System.IO namespace, 687, 996System.IO type, 709System.IO.FileMode enumeration, 704System.IO.IsolatedStorage namespace, 687, 698,

704System.IO.IsolatedStorage type, 702, 710System.IO.Pipes namespace, 873System.Linq namespace, 449System.Linq.Enumerable type, 454, 459, 462System.MarshalByRefObject class, 968System.Messaging namespace, 869System.MulticastDelegate class, 344–345, 1304System.MulticastDelegate/System Delegate

members, 345System.Net.PeerToPeer namespace, 873System.Net.Sockets namespace, 873System.Nullable<T> structure type, 139System.Object

overriding System.Object.Equals( ), 215–216overriding System.Object.GetHashCode( ),

216–217overriding System.Object.ToString( ), 215overview, 212–214shared members of, 218testing modified person class, 217

System.Object class, 84, 129, 529, 960, 968, 1073System.Object event, 975System.Object type, 431, 441, 1075System.Object.Equals( ) method, 215–216, 393System.Object.GetHashCode( ) method, 216–217System.Object.GetType( ) method, 117System.Object.ToString( ) method, 215SystemPens type, 987System.Query.dll assembly, 449System.Query.Func<A0, T> delegate types, 460System.Random member variable, 153System.Reflection namespace, 528, 530, 690,

1297–1298System.Reflection.Emit namespace, 424, 617,

648–649, 687System.Reflection.Emit.ILGenerator, 649–650System.Runtime.InteropServices namespace, 1306System.Runtime.Remoting namespaces, 869System.Runtime.Serialization namespace, 876, 880

■INDEX1364

Page 83: Appendixes - Springer

System.Runtime.Serialization.dll assembly, 876,880, 910

System.Runtime.Serialization.Formatters.Binarynamespace, 996

System.Runtime.Serialization.XmlFormatter type,910

System.Security.Policy namespace, 689System.Serializable attribute, structured exception

handling, 235System.ServiceModel namespace, 873, 876, 880,

885, 888<system.serviceModel> element, 889, 914System.ServiceModel.ClientBase<T> class, 897System.ServiceModel.Configuration namespace,

876System.ServiceModel.Description namespace, 876System.ServiceModel.dll assembly, 876, 885, 888,

904System.ServiceModel.MsmqIntegration

namespace, 876System.ServiceModel.Security namespace, 876System.String attribute, 1274System.String class, 69, 93System.String type, 92, 416, 1077System.SystemException, 230–231System.Text namespace, 93System.Text.StringBuilder class type, 69System.Threading namespace, 1258

Interlocked type, 594Monitor type, 594Mutex type, 594ParameterizedThreadStart delegate, 594,

597–598, 600–601Semaphore type, 594Thread type, 594ThreadPool type, 594, 610, 612ThreadPriority enum, 594ThreadStart delegate, 594, 598–599ThreadState enum, 594Timer type, 594TimerCallback delegate, 594, 609–610

System.Threading.Thread, 1327System.Type class, 528–530System.Uri types, 890System.ValueType class, 84, 129, 274–275System.Web namespace, ASP.NET 2.0, 1179System.Web namespace, Core ASP.NET Web-

centric, 1179<system.web> element, 1239, 1273System.Web.Caching namespace, 1179System.Web.Caching.Cache object, 1259System.Web.Hosting namespace, 1179System.Web.HttpApplication class, 1252–1253System.Web.HttpCookie type, 1267System.Web.Management namespace, 1179System.Web.Profile namespace, 1179System.Web.Security namespace, 1179System.Web.Services namespace, 870

System.Web.SessionState namespace, 1179System.Web.UI namespace, 1179System.Web.UI.Control class, 1250System.Web.UI.Control in ASP.NET, 1209–1210System.Web.UI.HtmlControls namespace, Core

ASP.NET Web-centric, 1179System.Web.UI.HtmlControls widget, 1214System.Web.UI.Page class, 1194, 1248System.Web.UI.Page type, 1253System.Web.UI.Page-derived type, 1200, 1263System.Web.UI.Page.Request property, 1196System.Web.UI.StateBag type, 1250System.Web.UI.TemplateControl class, 1194System.Web.UI.WebControls namespace, 1179,

1207–1208System.Web.UI.WebControls.Panel class, 1210System.Web.UI.WebControls.WebControl.

WebControl class, 1208System.Web.UI.x namespace, ASP.NET 2.0, 1179System.Window.Application class type, 1006System.Windows namespace, 1005, 1123System.Windows.ContentControl class, 1008System.Windows.Controls namespace, 1005, 1014,

1059, 1084System.Windows.Controls.Button type, 1157System.Windows.Controls.ContentControl class,

1007–1008System.Windows.Controls.Control class,

1008–1009System.Windows.Controls.Primitives namespace,

1071System.Windows.Data namespace, 1106System.Windows.DependencyObject class, 1010,

1063System.Windows.DependencyProperty class type,

1062System.Windows.Documents namespace, 1083System.Windows.Forms namespace, 270, 956, 1208System.Windows.Forms.ColorDialog type, 994System.Windows.Forms.ContainerControl class,

969System.Windows.Forms.Control class, 958,

968–969System.Windows.Forms.dll assembly, 955, 999System.Windows.Forms.Form class, 969System.Windows.Forms.Form file, 983System.Windows.Forms.Form-derived type, 1013System.Windows.Forms.MouseEventHandler

delegate, 975System.Windows.Forms.ScrollableControl class,

968System.Windows.Input.KeyEventHandler delegate,

1020System.Windows.Markup namespace, WPF, 1005System.Windows.Media namespace, 1005, 1123System.Windows.Media.Animation namespace,

1117, 1137, 1142System.Windows.Media.Brush namespace, 1127

■INDEX 1365

Finditfasterathttp://superindex.apress.com

/

Page 84: Appendixes - Springer

System.Windows.Media.Color type, 1127System.Windows.Media.Drawing abstract class,

1119System.Windows.Media.Drawing class, 1130System.Windows.Media.Drawing namespace, 1118System.Windows.Media.Geometry base class, 1131System.Windows.Media.Shapes types, 1131System.Windows.Media.Timeline base class, 1138System.Windows.Media.Visual class, 1010, 1120System.Windows.Media.Visual namespace, 1118System.Windows.Navigation namespace, WPF,

1005System.Windows.RoutedEventArgs parameter,

1064System.Windows.Shapes namespace, 1005, 1118,

1124System.Windows.Threading.DispatcherObject

class, 1011System.Windows.UIElement base class, 1010System.Windows.Window type, 1006System.Workflow.Activities namespace, 921, 924System.Workflow.Activities.dll core assembly, 924System.Workflow.ComponentModel.dll core

assembly, 924System.Workflow.Runtime namespace, 924System.Workflow.Runtime.dll assembly, 924System.Workflow.Runtime.Hosting namespace,

924System.Xml namespace, 448, 1115System.Xml.dll assembly, 858System.Xml.Linq namespace, 859, 862System.Xml.Linq.dll assembly, 449System.Xml.XLinq.dll assembly, 449

T\t character, 89TabControl control, 1056TabIndex property, 969, 981, 1213TabIndex value, 1114Table property, 787, 790[Table] attribute, 845, 847TableAdapter component, 824TableAdapterManager type, 834TableAttribute type, 845TableMappings property, 810TableName member, 793TableName property, 811Tables property, 784–785Table<T> member variables, 846Table<T> type, 856Table<T>-compatible property, 852TabStop property, 969, 981Tag property, 1080/target: flag, 1321Target property, System.MulticastDelegate/System

Delegate, 345/target:exe option, 957TargetProperty property, 1141

*.targets files, 1023, 1025TargetSite property, System.Exception, 222, 227TargetType property, 1151–1152template, exception code expansion, 235Template property, 1156, 1159templating services, 1008temporary cookie, 1267TerminateActivity, WF, 921TesterUtilClass class, 425Text property, 960, 970, 1107, 1197, 1200, 1212,

1214TextBlock type, 1096TextBox control, 980, 1056, 1209TextBox type, 817, 1081, 1102, 1105, 1152TextBox widget, 1210, 1232TextBoxStyle style, 1152TextChanged event, 1209TextPad development editor

configuring for C#, 42–43executing programs, 44predefined run commands, 45

TextWriter, System.IO, 678–679Theme, Page Type properties, ASP.NET, 1195Theme property, Page Type, 1195themes, 1178

* skin files, 1238–1239applying at page level, 1240applying sitewide, 1239–1240assigning programmatically, 1241–1242overview, 1237SkinID property, 1240

Thickness property, 1130this keyword, 147, 149, 425this[ ] syntax, indexer methods, 384Thread class, 583Thread type, 594–597ThreadPool type, System.Threading Namespace,

594, 610, 612threads

example code, 566–567multithreading, 562overview, 562suspended during garbage collection, 248Thread Local Storage (TLS), 563time slice, 563

ThreadStart delegate, System.Threadingnamespace, 594, 598–599

ThreadState method, Thread type, 595ThreeDCircle type, 209ThrowActivity, WF, 921ThrowException( ) method,

System.Reflection.Emit.ILGenerator, 650time slice, 563Timeout property, 1266Timer control, 609TimerCallback delegate, System.Threading

namespace, 594, 609–610

■INDEX1366

Page 85: Appendixes - Springer

TimeSpan object, 1139–1140TimeSpan structure, 94Title property, 76, 1066<title> tags, 1169*.tlb file, 1292, 1311/tlb flag, 1310tlbimp.exe utility, 1296–1298, 1301, 1304To property, 1138–1139ToArray<T>( ) method, 456, 471ToDictionary<K,T>( ) method, 456ToggleButton control, 1056ToList<T>( ) method, 456ToLower( ) method, 89ToolBar control, 1056<ToolBar> type, 1096<ToolBarTray> element, 1096ToolsSpellingHints_Click( ) method, 1095ToolStripMenuItem type, 959–960ToolTip control, 1056ToolTip property, WebControl base class, 1213Top property, 1086ToString( ) method, 123, 213–216, 441–443, 464,

467, 845, 1077, 1079, 1111TotalProcessorTime, ProcessThread type, 568ToUpper( ) method, 89, 92Trace attribute, 1189

<%@Page%> directive, 1184trace element, Web.config, ASP.NET, 1204Trace property, 1189, 1195<trace> element, web.config File, 1204tracing support, 1189Tracking services, WF, 920Transaction object, ADO.NET data providers, 734Transaction services, WF, 920Transform abstract base class, 1134Transform property,

System.Windows.Media.Geometry baseclass, 1131

<TransformGroup> type, 1135–1136TreeView control, 1056, 1220TreeView type, 1220<Trigger> element, 1142Trim( ) method, 87triple tick (''') code comment notations, 177try keyword, 98tunneling event, 1065TwoWay mode, 1105txtColor control, 980txtMake control, 980txtPrice control, 980type attribute, 1171, 1278Type attribute, Profile Data, 1274Type class, 905type constructors, CIL, 636–637Type Libraries node, 1294type library, 1292type parameters, 309

type reflectionAssemblyRef, 526description, 527external private assemblies, 536–537fields and properties, 531implemented interfaces, 531and metadata, 523–526method parameters and return values, 534–535methods, 530–531overview, 523shared assemblies, 538–539TypeDef, 524–525TypeRef, 524–525User Strings, 527

typed exceptions, structured exception handling,241

TypeDef, 524–525TypedTableBaseExtensions type, 840TypeDumper.DumpTypeToFile( ) method, 1327typeof operator, 123, 530TypeRef, 524–525TypeResolve event, System.AppDomain, 573types, five categories of, 17

UUI elements, 1001UIElement base class, 1010, 1132UIElement element, 1119uint data type, 80ulong data type, 80Unadvise( ) method, 307unbound type parameters, 334Unchanged value, 791Unchecked events, 1070unchecked keyword, 69, 97, 100#undef, preprocessor directive, 411, 413–414unhandled exceptions, structured exception

handling, 241UnhandledException event, System.AppDomain,

573UninstallSqlState.sql file, 1271unique name/value type pairs, 444Unique property, 787Unload event, Page type, 1201Unload( ) method, System.AppDomain, 572Unlock( ) method, HttpApplicationState type, 1255unmanaged code, 1283unmanaged resources, 252, 256–263unsafe compiler flag, 405unsafe keyword, 405–407Update( ) method, 808UpdateCarInventory( ) method, 1261UpdateCheck property, 848UpdateCommand property, 812UpdateInventory( ) method, 813–814updating applications using shared assemblies,

512

■INDEX 1367

Finditfasterathttp://superindex.apress.com

/

Page 86: Appendixes - Springer

updating records, ADO.NET, 765Uri class, 905user errors, description, 219user interface in HTML, 1170–1171/user option, 848UserControls, 1216UserHostAddress member, HttpRequest Type, 1196UserHostName member, HttpRequest Type, 1196UserName property, 76userName string member variable, 929UserShoppingCart class, 1264UserTheme session variable, 1242ushort data type, 81using keyword, 261–262, 478–479UsingNamespace( ) method,

System.Reflection.Emit.ILGenerator, 650

VValidateInput( ) method, HttpRequest type, 1196validating form data, ASP.NET, 1174validation controls, ASP.NET

CompareValidator control, 1231, 1233CustomValidator control, 1231defining validation groups, 1235–1236RangeValidator control, 1231, 1233RegularExpressionValidator control, 1231, 1233RequiredFieldValidator control, 1231–1232ValidationSummary control, 1231, 1234

validation schemes, 1168ValidationExpression property, 1233ValidationSummary control, ASP.NET, 1231, 1234ValidationSummary widget, 1234value and reference types, conversion, 316Value property, 137, 767, 1214value types, 107, 136, 316<value> code comment, XML Elements, 177value-based semantics, 215, 444ValueChange event, 1103var keyword, 415, 417, 441, 470variables, local, CIL, 640Variant data type, 419, COMVARIANT types, 1298variant-compliant data type, 1283VB 2005 class type, 141–144VB6 language deficiencies, 4VB6 String data type, 1290Vb6ComCarServer.dll, 1301vbnc compilers, 1321VBScript support, 1173vector graphics, 1002verbatim string, 90VerifyDuplicates( ) method, 434–435version number of assemblies, 481Vertical property, 1088VerticalAlignment property, 1156VeryComplexQueryExpression type, 464VideoDrawing type, 1130

View Class Diagram button, Solution Explorerwindow, 190

View In Browser menu option, 1183view state, 1212, 1248–1250Viewbox control, 1056/views option, 848VIEWSTATE field, 1248, 1250ViewState property, 1250–1251, 1256virtual directory, 1165virtual execution stack, 620virtual keyword, description, 199virtual member, 162, 201virtual methods, 200, 204Visible member, System.Web.UI.Control, 1210Visible property, System.Web.UI.Control in

ASP.NET, 1210Visual Basic 2005 benefits and features, 8–9Visual Basic .NET integration with C#, 494–495,

498Visual Basic snap-in example, 555Visual C# Express, 51–52Visual Studio 2003, 36Visual Studio 2005, 366–367Visual Studio 2008

additions available, 52–53automated coding support, 58building WPF applications using, 1044–1048Class View, 55code refactoring support, 56FxCop, 65integrated Help system, 64interface implementation, 282Lutz Roeder’s Reflector for .NET, 65NAnt, 65NDoc, 65.Net Framework Documentation system, 63–64New Project dialog box, 53Nunit, 65Object Test Bench, 62overview, 52project configuration (Project Properties), 55refactoring example, 57refactoring techniques available, 56–57Snippets automated coding, 58Solution Explorer, 53Surround With automated coding, 58Visual Class Designer, 59–62

VisualBrush type, 1127VisualChildrenCount read-only property, 1122Visual-derived types, 1120, 1123void return value, 71/vpath: option, 1167

WWaitReason, ProcessThread type, 568WCF client, 879WCF Service assembly, 879WCF Service host, 879

■INDEX1368

Page 87: Appendixes - Springer

WcfTestClient.exe application, 915web applications in ASP.NET, 1203–1204, 1207web controls in ASP.NET, 1207–1209web enhancements, .NET 3.5, 1178web page code model, ASP.NET, 1179, 1181web paradigm, 1177web parts, 1178Web Service Description Language (WSDL), 895Web Services Enhancements (WSE) 3.0, 873Web Site template, 1190web-centric primer, 1177Web.config, ASP.NET, 1204, 1269–1270Web.config file, 878, 913–914, 1163, 1178, 1188,

1191, 1203–1204, 1271–1272, 1274WebControl class properties, ASP.NET, 1213WebDev.WebServer.exe utility, 1166–1167, 1178,

1183WebMethod attribute, 543, 870WebService directive, 871WebServiceFaultActivity, WF, 921WebServiceInputActivity, WF, 921WebServiceOutputActivity, WF, 921website administration utility, ASP.NET, 1205–1206website directory structure, ASP.NET, 1190Web.sitemap file, 1219where keyword, generics, 335Where( ) method, 461where operator, 463, 466Where<T>( ) method, 461While activity, 928–930while loop, 101, 795WhileActivity, WF, 921widening, 95widgets, 1169, 1248Width member, 1061Width property, 1085, 1137, 1213Width value, 1087Win 32 binaries (*.dll or *.exe), 11Win32 file header in assemblies, 482Window class

overview, 1006–1007System.Windows.Controls.ContentControl base

class, 1007–1008System.Windows.Controls.Control base class,

1008–1009System.Windows.DependencyObject base class,

1010System.Windows.Media.Visual base class, 1010System.Windows.Threading.DispatcherObject

base class, 1011System.Windows.UIElement base class, 1010

Window objectclosing of, 1018–1019lifetime of, 1017–1018

Window type, 1083, 1094, 1103, 1113, 1118<Window> element, 1022, 1032, 1084, 1113, 1154Window1 type, 1108Window-derived type, 1121

WindowHeight property, 76WindowLeft property, 76<Window.Resources> element, 1149Windows collection, 1016Windows Communication Foundation (WCF), 867Window’s constructor, 1060Windows Distributed interNet Applications

Architecture (DNA) deficiencies, 5–6Windows Forms, 556–557, 999Windows Presentation Foundation (WPF), 955,

1318. See also Application type; Windowobject

assembliesoverview, 1005role of Application class, 1006role of Window class, 1006–1011

building WPF applications using Visual Studio2008, 1044–1048

building XAML-free WPF applicationscreating simple user interface, 1013–1015,

1021extending Window class type, 1013overview, 1011–1013

controlling content layout using panels, 1108Extensible Application Markup Language

(XAML)attached properties, 1038–1039Browser Applications (XBAPs), 1004defining application object in, 1023, 1033defining MainWindow in, 1022–1023elements and attributes, 1035experimenting with using XamlPad, 1032markup extensions, 1039–1041overview, 1021–1022processing at runtime, 1048–1052processing XAML files via msbuild.exe,

1023–1024property-element syntax, 1036–1037type converters, 1039

motivation behindoverview, 999–1000providing optimized rendering model, 1001providing separation of concerns via XAML,

1001separation of concerns using code-behind files,

1029–1030transforming markup into .NET assembly

mapping XAML to C# code, 1025–1026overview, 1025role of Binary Application Markup Language

(BAML), 1026–1028XAML-to-assembly process summary,

1028–1029, 1052Windows property, Application type, 1006Windows Vista operating system, 1001Windows Workflow Foundation (WF)

assemblies and core namespaces, 924brief word regarding custom activities, 951–952

■INDEX 1369

Finditfasterathttp://superindex.apress.com

/

Page 88: Appendixes - Springer

building blocks ofgetting into flow of workflow, 925–926integrated services of WF, 919overview, 918–919role of sequential workflows and state

machine workflows, 921–923WF activities, 920–921

building reusable code library, 948–951building simple workflow-enabled application

adding Code activity, 927–928adding custom start-up parameters, 931–935adding While activity, 928–930initial workflow code, 926–927overview, 926WF engine hosting code, 930–931

invoking web services within workflows,934–935

motivation behind, 917–918overview, 917

Windows Workflow toolbox, 920Windows XP Home Edition and ASP.NET,

1166–1167WindowsBase.dll assembly, WPF, 1005Windows.Forms coding, 977WindowsFormsDataTableViewer application, 799WindowState property, 972WindowTop property, 76WindowWidth property, 76WinFormsClientApp.cs file, 1328Wizard definition, 1229Wizard web control, 1228worker thread, 562WorkflowCompleted event, WorkflowRuntime, 931workflow-enabled application, 918WorkflowInstance core type, 930WorkflowRuntime core type, 930WorkflowTerminated event, WorkflowRuntime, 931WrapPanel control, 1056, 1085, 1088<WrapPanel> element, 1114Write( ) method, 676, 678, 682, 1189, 1199WriteAllBytes( ) method, 674WriteAllLines( ) method, 674WriteAllText( ) method, 674WriteFile( ) method, 70, 153, 678, 1199write-only class properties, 171WriteOnly keyword, 165, 171write-only property, 171WriteTextToIsoStorage( ) method, 707WriteXml( ) method, 796WriteXmlSchema( ) method, 796writing to a text file, 679wsdl utility, 1322wsdl.exe command-line tool, 872WSDualHttpBinding class, 882WSDualHttpBinding option, 881WSFederationHttpBinding class, 882

WSFederationHttpBinding option, 881WSHttpBinding class, 905WSHttpBinding option, 881WSHttpBinding protocol, 882, 901

XX or x string format, .NET, 78X property, 976*.xaml file, 1024, 1028, 1055, 1129XamlPad, 1031–1032XAttribute member, 859XAttributes object, 859x/COL/Type markup extension, 1151XComment member, 859Xcopy deployment, 499XDeclaration member, 859XDocument member, 859XDocument type, 860XElement member, 858XElement parameter, 864XElement type, 860XElement.Descendants( ) method, 863XElement.Load( ) method, 863XElements object, 859XML

and ADO.NET, 731/doc compiler flag, 179documentation elements, 177documenting VB 2005 source code via, 176–180source code documentation, 176–177

*.xml file, 179, 1114XmlDataProvider type, 1114XmlElement type, 1115xmlns attribute, 1168XmlReader/XmlWriter models, 858XmlSerializer, 716, 720–722XName/XNamespace member, 859XPath bindings, 1114xPos member variable, 437xsd utility, 1322xsp2 utility, 1322

Yy operators, 448Y property, 976yetAnotherPoint variable, 437yield keyword, 292–293yPos member variable, 437

■INDEX1370