Calling .NET from Mathematica

Introduction

.NET/Link provides Mathematica users with the ability to interact with arbitrary .NET types directly from Mathematica. You can create objects and call methods and properties directly in the Mathematica language. You do not need to write any .NET code, or prepare in any way the .NET types you want to use. You also do not need to know anything about MathLink. In effect, all of .NET becomes a transparent extension to Mathematica, almost as if every existing and future .NET type were written in the Mathematica language itself.
We call this facility "installable .NET" because it generalizes the ability that Mathematica has always had to plug in extensions written in other languages through the Install function. Compared to other languages like C or C++, however, .NET/Link makes the intermediate steps go away completely, which is why we say that .NET becomes a transparent extension to Mathematica.
Although .NET is sometimes referred to as an interpreted environment, this is really a misnomer. To use .NET you must write a complete program in a language like C#, compile it, and then execute it. Mathematica users have the luxury of working in a true interpreted, interactive environment that lets them experiment with functions and build and test programs a line at a time. .NET/Link brings this same productive environment to .NET programmers. You could say that Mathematica becomes a scripting language for .NET.
To Mathematica users, then, the "installable .NET" feature of .NET/Link opens up the universe of .NET types as an extension to Mathematica; for .NET users, it allows the extraordinarily powerful and versatile Mathematica environment to be used as a shell for interactively developing, experimenting with, and testing .NET programs.
This guide discusses calling from Mathematica into the .NET runtime. You will see how to load .NET assemblies and types into Mathematica, create objects of these types, call methods and properties, and so on. You will also learn how to use .NET/Link to call COM objects as well as standard C-style DLL functions.
Simple Examples:
GUI Examples:
Calling DLLs:
Calling COM Objects:

Loading the NETLink` Package

You must load the .NET/Link package before you can use .NET/Link.
Click for copyable input

Launching the .NET Runtime

The InstallNET function is used to launch the .NET runtime.
Click for copyable input
If you are actively developing .NET classes and other types to use in Mathematica, you will need to restart the .NET runtime before you can reload a modified version of a class. Use the ReinstallNET function to quit and restart the .NET runtime. Most users will have no need to ever quit or restart .NET and should avoid calling ReinstallNET or UninstallNET. Remember that the .NET runtime is shared by potentially many programs in your Mathematica session. Shutting down or restarting the .NET runtime could have unexpected consequences for those programs.
InstallNET[]launch the .NET runtime and prepare it for use from Mathematica
ReinstallNET[]quit and restart the .NET runtime
NETLink[]give the LinkObject that is being used to communicate with the .NET runtime

Launching the .NET runtime.

Loading .NET Assemblies and Types

.NET Assemblies

Programs and libraries for .NET are packaged into units called assemblies. An assembly can be defined as a versioned, self-describing binary (DLL or EXE) containing a collection of types (classes, interfaces, structs, and so on) and optional resources. An assembly can span multiple files (a multi-file assembly), or a single file can contain more than one assembly, but in the typical case an assembly consists of a single DLL or EXE file. Although .NET assemblies can have the DLL extension, internally they are quite different from old C-style DLLs. Conceptually, though, a .NET DLL is similar to a C-style DLL in that they are both libraries of code intended to be loaded and called by other programs. An EXE assembly is an executable program that can be launched directly, but it also can export types like a DLL for use by other programs.
Assemblies can be located anywhere on your system. The .NET Framework maintains a special location on your system where assemblies can be stored so that they can easily be found by all .NET programs on the system. This location is called the Global Assembly Cache (GAC), and is found in the assembly subdirectory of your root Windows directory. The assemblies that are part of the .NET Framework itself are located in the GAC, and many .NET programs that you install will put assemblies there. There is no requirement that an assembly be placed into the GAC, and .NET/Link can use assemblies located anywhere on your system.
Because all .NET types are packaged into assemblies, to load a type into Mathematica you first need to load its assembly. You use the LoadNETAssembly function to load an assembly into .NET/Link. Assemblies can be loaded by specifying various types of information about the assembly, such as a full path to the assembly file, or by a full or partial name of the assembly. Assembly names will be discussed in more detail later, but for now it suffices to say that assembly names are assigned by their creators, and may bear no resemblance to the name of the actual assembly file. An example of a simple assembly name is System.XML, which is the assembly in the .NET Framework that handles XML-related functionality. Assemblies are often named after the most important namespace they define. The actual file name of the System.XML assembly is System.XML.dll, and it is located somewhere nested deep down inside the GAC.
.NET/Link does not need to be explicitly instructed to load all assemblies. It will automatically load any of the .NET Framework assemblies, meaning all of the assemblies containing types whose names start with System. (e.g., System.Windows.Forms.Form, System.Drawing.Rectangle, System.Data.DataSet, and so on). Most of the types that you will use in .NET/Link programming are found in the system assemblies. You will have to manually load other assemblies. The LoadNETAssembly function, described later in this tutorial, is the Mathematica function you use to load assemblies into .NET/Link and prepare them to be used from Mathematica.

.NET Types

A type is the fundamental unit of .NET programming. Every type falls into one of the following categories: classes, interfaces, structs ("value types"), enumerations, and delegates. Every object in .NET is an instance of some type. Although the set of types is broader than just classes, you might find it easier to think of types as being classes.
Types are defined in assemblies. To load and use a type in .NET/Link, you must first load the assembly in which it resides and then load the type itself. Often these steps can be combined into a single operation. LoadNETType, described later , is the Mathematica function that you use to load types into .NET/Link so they can be used from Mathematica.

LoadNETAssembly

LoadNETAssembly is the function you use to load assemblies into .NET/Link so that the types they contain can be used from Mathematica. LoadNETAssembly has a number of different argument sequences. Although all these different possible arguments might seem confusing, the basic principle is to allow virtually any way of specifying enough information about the assembly so that .NET/Link can locate it.
LoadNETAssembly[assemblyName]load the specified assembly based on its name, such as "System.Web"
LoadNETAssembly[path]load the assembly based on its full file path
LoadNETAssembly[url]load the assembly pointed to by this URL
LoadNETAssembly[assemblyName,dir]load the assembly based on its name and the directory in which it resides
LoadNETAssembly[assemblyName,context`]load the assembly based on its name and the application context in which it resides
LoadNETAssembly[dir]load all the assemblies in this directory
LoadNETAssembly[context`]load all the assemblies in this application context

Loading assemblies.

Here is an example of using LoadNETAssembly to load an assembly that is part of the .NET Framework.
In[3]:=
Click for copyable input
Out[3]=
The return value of LoadNETAssembly is a NETAssembly expression. This is not a .NET object itself, just a special expression that can be used in .NET/Link to refer to a loaded assembly in various functions that take an assembly specification as an argument.
The name used in the previous example is the simple name of the assembly. The actual full name, or display name, of the assembly is longer and contains version information, among other things. You can use the full name if you want to force a certain version to be loaded (note that if you execute this on your machine, it will fail unless you have exactly the same version of the .NET Framework installed).
In[4]:=
Click for copyable input
Out[4]=
We were able to load this assembly based on only its name, without any location information, because it is located in the GAC.
As another example of LoadNETAssembly, say you have obtained an assembly or created one of your own in some .NET language and want to load it into .NET/Link to use from Mathematica. The assembly is in the file c:\MyProgram\Bin\Debug\MyAssembly.dll. Here is how you would load it.
Click for copyable input
Loading an assembly by specifying its path is useful for assemblies that you have created yourself.
LoadNETAssembly can also load assemblies from an assembly subdirectory in a Mathematica application directory. This is intended for developers who are creating applications that use .NET/Link. If you have a Mathematica application directory called MyApp, and it is installed into one of the standard locations for Mathematica applications (e.g., <Mathematica dir>\AddOns\Applications), you can give the MyApp directory a subdirectory named assembly and place all the extra assemblies that your application needs into the assembly directory. Your application's Mathematica code can then load one of these application assemblies by supplying the assembly name and the context that corresponds to your application.
Click for copyable input
In this way, application developers can bundle private assemblies in their application layout and not require that their users perform any special installation steps such as copying assemblies into the GAC.

LoadNETType

LoadNETType is the Mathematica function that loads .NET types so that they can be used from Mathematica. It is often not necessary to explicitly call LoadNETType. Whenever a .NET object is returned to Mathematica, its type is loaded. This means that if you want to create a new object of a certain type, you can just call NETNew and the type will be loaded when the object is returned to Mathematica. The most common reason for calling LoadNETType directly is if you want to use a static method or property from a type. In that case, you are not creating an object with NETNew, so you must manually load the type.
LoadNETType[typeName]load the specified type
LoadNETType[typeName,assemblyName]load the type from the specified assembly
LoadNETType[typeName,NETAssembly]load the type from the assembly identified by a NETAssembly expression
LoadNETType[typeName,assemblyName,context`]load the type from the specified assembly residing in the specified application context

Loading types.

Here is a simple example of LoadNETType.
In[5]:=
Click for copyable input
Out[5]=
The return value of LoadNETType is a NETType expression. This is not a .NET object itself, just a special expression that can be used in .NET/Link to refer to a .NET type in various functions that take a type specification as an argument.
Note that you must supply the full type name, including the namespace prefix (System.Windows.Forms in this example). For the load to succeed, the assembly in which the type resides must be already loaded using LoadNETAssembly. As mentioned earlier, assemblies for all System types are automatically loaded as needed by .NET/Link, so there was no need to load the System.Windows.Forms assembly manually in the previous example.

Viewing Loaded Assemblies and Types

You can use the utility functions LoadedNETAssemblies. and LoadedNETTypes to see what assemblies and types have been loaded into the current Mathematica session. These are intended mainly for debugging purposes.
LoadedNETAssemblies[]return a list of all assemblies loaded into Mathematica
LoadedNETTypes[]return a list of all types loaded into Mathematica

Viewing loaded assemblies and types.

Contexts and Visibility of Static Type Members

LoadNETType has two options that let you control the naming and visibility of static methods and fields. To understand these options, you need to understand the problems they help to solve. We have to get a bit ahead of ourselves to explain the issues, since we have not yet discussed how to call .NET methods. When a type is loaded, definitions are created in Mathematica that allow you to call methods, properties, and fields of objects of that class. Static members are treated quite differently from nonstatic ones. Say you have a class named MyClass in the namespace MyCompany.Utilities, and this class contains a static method named Foo. When you load this class, a definition must be set up for Foo so that it can be called by name, something like Foo[args]. The question becomes: In what context do you want the symbol Foo defined, and do you want this context to be visible (i.e., on $ContextPath)?
.NET/Link always creates a definition for Foo in a context that mirrors its fully qualified classname: MyCompany`Utilities`MyClass`Foo. This is done to avoid conflicting with symbols named Foo that might be present in other contexts. However, you might find it clumsy to have to call Foo by typing the full context name every time, as in MyCompany`Utilities`MyClass`Foo[args]. The option AllowShortContext->True (this is the default setting) causes .NET/Link to also make definitions for Foo accessible in a shortened context, one that consists of just the class name without the hierarchical namespace prefix. In our example, this means that you could call Foo as simply MyClass`Foo[args]. If you need to avoid use of the short context because there is already a context of the same name in your Mathematica session, you can use AllowShortContext->False. This forces all names to be put only in the "deep" context. Note that even with AllowShortContext->True, names for statics are also put into the deep context, so you can always use the deep context to refer to a symbol if you desire.
AllowShortContext, then, lets you control the context where the symbol names are defined. The other option, StaticsVisible, controls whether this context is made visible (put on $ContextPath) or not. The default is StaticsVisible->False, so you have to use a context name when referring to a symbol, as in MyClass`Foo[args]. With StaticsVisible->True, MyClass` will be put on $ContextPath, so you could just write Foo[args]. Having the default be True would be a bit dangerous—every time you load a class a potentially large number of names would suddenly be created and made visible in your Mathematica session, opening up the possibility for all sorts of "shadowing" problems if symbols of the same names were already present (see Contexts for a discussion of contexts and shadowing problems).
For these reasons StaticsVisible->True is recommended only for classes that you have written, or ones whose contents you are familiar with. In such cases, it can save you some typing, make your code more readable, and prevent the all-too-easy bug of forgetting to type the classname prefix. A classic example would be implementing the venerable "addtwo" MathLink example program. In C#, it might look like this.
With the default StaticsVisible->False, you would have to call addtwo as AddTwo`AddTwo[3, 4]. Setting StaticsVisible->True lets you write the more obvious AddTwo[3, 4].
Be reminded that these options are only for static methods and fields. As discussed later, nonstatics are handled in a way that makes context and visibility issues go away completely.
StaticsVisibleTruemake static methods and fields accessible by just their names, not in a special context
AllowShortContextFalsemake static methods and fields accessible only in the context that mirrors the full hierarchical namespace name

Options for LoadNETType.

Conversion of Types Between .NET and Mathematica

Before we encounter the operations of creating .NET objects and calling methods, we should examine the mapping of types between Mathematica and .NET. When a .NET method returns a result to Mathematica, the result is automatically converted into a Mathematica expression. For example, .NET integer types (e.g., Int32, Byte, and so on), are converted into Mathematica integers, and .NET real number types (Single, Double) are converted into Mathematica reals. The table below shows the complete set of conversions. These conversions work both ways—for example, when a Mathematica integer is sent to a .NET method that requires a Byte value, the integer is automatically converted to a .NET Byte.
Note that this table gives type names as they are used in the .NET Framework. Different languages often have their own keywords that map to these underlying types. In C#, for example, the keyword int is an alias to the Int32 type, and in Visual Basic .NET the Int32 type is called Integer.
.NET type
Mathematica type
Byte, SByte, Char, Int16, UInt16, Int32, UInt32, Int64, UInt64Integer
DecimalIntegeror Real
Single, DoubleReal
BooleanTrue or False
StringString
ArrayList
controlled by userComplex
ObjectNETObject
Exprany expression
nullNull

Corresponding types in .NET and Mathematica.

.NET arrays are mapped to Mathematica lists of the appropriate depth. Thus, when you call a method that takes a double[] (in C# notation), you might pass it {1.0, 2.0, N[Pi], 1.23}. Similarly, a method that returns a two-deep array of integers (int[,] in C# notation) might return to Mathematica the expression {{1, 2, 3}, {5, 3, 1}}.

Creating Objects

To construct .NET objects, use the NETNew function. The first argument to NETNew is the object's type, specified either as a NETType expression returned from LoadNETType or as a string giving the fully qualified type name (i.e., including the namespace prefix). If you wish to supply any arguments to the object's constructor, they follow as a sequence after the type.
NETNew[typeName,arg1,...]construct a new object of the specified class and return it to Mathematica
NETNew[NETType,arg1,...]construct a new object of the specified class and return it to Mathematica

Constructing .NET objects.

For example, this will create a new Form.
In[6]:=
Click for copyable input
Out[6]=
The return value from NETNew is a strange expression that looks like it has the head NETObject, except that it is enclosed in angle brackets. The angle brackets are used to indicate that the form in which the expression is displayed is quite different from its internal representation. These expressions will be referred to as NETObject expressions. NETObject expressions are displayed in a way that shows their type name, but you should consider them opaque, meaning that you cannot pick them apart or peer into their insides. You can only use them in .NET/Link functions that take NETObject expressions.
NETNew invokes a .NET constructor appropriate for the types of the arguments being passed in, and then returns to Mathematica what is, in effect, a reference to the object. That is how you should think of NETObject expressions—as references to .NET objects very much like object references in a .NET language like C# or Visual Basic .NET. What is returned to Mathematica is not large no matter what type of object you are constructing. In particular, the object's data (that is, its fields) are not sent back to Mathematica. The actual object remains on the .NET side, and Mathematica gets a reference to it.
The previous examples specified the class by giving its name as a string. You can also use a NETType expression, which is a special expression returned by LoadNETType that identifies a class. When you specify the class name as a string, the class is loaded if it has not already been.
In[7]:=
Click for copyable input
NETNew is not the only way to get a reference to a .NET object in Mathematica. Many methods and properties return objects, and when you call such a method or property, a NETObject expression is created. Such objects can be used in the same way as ones you explicitly construct with NETNew.

Calling Methods, Properties, and Fields

Syntax

The Mathematica syntax for calling .NET methods and accessing fields is very similar to the syntax used in C# and Visual Basic .NET. The box below compares the Mathematica and C# ways of calling constructors, methods, properties, fields, static methods, static properties, and static fields. You can see that Mathematica programs that use .NET are written in almost exactly the same way as C# (or VB .NET) programs, except Mathematica uses [] instead of () for arguments and @ instead of the . (dot) as the "member access" operator.
An exception is that for static methods, Mathematica uses the context mark ` in place of the dot used by C# and VB. This parallels the usage in those languages also, as their use of the dot in this circumstance is really as a scope resolution operator (like :: in C++). Although Mathematica does not use this terminology, its scope resolution operator is the context mark. .NET namespace names map directly to Mathematica's hierarchical contexts.
Constructors
C#:MyClass obj = new MyClass(args);
Mathematica:obj = NETNew["MyClass", args];
Methods
C#:obj.MethodName(args);
Mathematica:obj@MethodName[args]
Properties and fields
C#:obj.PropertyOrFieldName = 1; value = obj.PropertyOrFieldName;
Mathematica:obj@PropertyOrFieldName = 1; value = obj@PropertyOrFieldName;
Static methods
C#:MyClass.StaticMethod(args);
Mathematica:MyClass`StaticMethod[args];
Static properties and fields
C#:MyClass.StaticPropertyOrField = 1; value = MyClass.StaticPropertyOrField;
Mathematica:MyClass`StaticPropertyOrField = 1; value = MyClass`StaticPropertyOrField;

C# and Mathematica syntax comparison.

You may already be familiar with @ as a Mathematica operator for applying a function to an argument: f @ x is equivalent to the more commonly used f[x]. .NET/Link does not usurp @ for some special operation—it is really just normal function application slightly disguised. This means that you do not have to use @ at all. The following are equivalent ways of invoking a method.
Click for copyable input
The first form preserves the natural mapping of the syntax of most .NET languages into Mathematica and will be used exclusively in this manual.
When you call methods, properties, or fields and get results back, .NET/Link automatically converts arguments and results to and from their Mathematica representations according to the table presented earlier.
In object-oriented languages, method and field names are scoped by the object on which they are called. In other words, when you write obj.Meth(), .NET languages know that you are calling the method named Meth that resides in obj's class, even though there may be other methods named Meth in other classes. .NET/Link preserves this scoping for Mathematica symbols so that there is never a conflict with existing symbols of the same name. When you write obj@Meth[], there is no conflict with any other symbols named Meth in the system—the symbol Meth used by Mathematica in the evaluation of this call is the one set up by .NET/Link for this class. Here is an example using a field. First, we create a Point object.
In[9]:=
Click for copyable input
Out[9]=
The Point class has fields named X and Y, which hold its coordinates. A user's session might also have symbols named X or Y in it, however. Let us set up a definition for X that will tell us when it is evaluated.
In[10]:=
Click for copyable input
Now set a value for the field named X (this would be written as pt.X = 42 in C# or VB).
In[11]:=
Click for copyable input
You will notice that "gotcha" was not printed. There is no conflict between the symbol X in the Global` context that has the Print definition and the symbol X that is used during the evaluation of this line of code. .NET/Link protects the names of members on the right-hand side of @ so that they do not conflict with, or rely on, any definitions that might exist for these symbols in visible contexts.
In summary, for nonstatic methods, properties, and fields, you never have to worry about name conflicts and shadowing, no matter what context you are in or what the $ContextPath is at the moment. This is not true for static members, however. Static methods and fields are called by their full name, without an object reference, so there is no object out front to scope the name. Here is a simple example of a static method call that invokes the .NET garbage collector. We need to call LoadNETType before we call a static method to make sure the class has been loaded.
In[12]:=
Click for copyable input
The name scoping issue is not usually a problem with static members because they are defined in their own contexts (GC` in this example). These contexts are usually not on $ContextPath, so you do not have to worry that there is a symbol of the same name in the Global` context or in a package that has been read. If there is already a context named GC` in your session, and it has its own function Collect, you can always avoid a conflict by using the fully-hierarchical context name that corresponds to the full type name for a static member.
In[14]:=
Click for copyable input

Underscores in .NET Names

.NET names can have characters in them that are not legal in Mathematica symbols. The only common one is the underscore. .NET/Link maps underscores in type, method, property, and field names to 'U'. Note that this mapping is only used where it is necessary—when names are used in symbolic form, not as strings. For example, assume you have a class named My_Class. When you refer to this class name as a string, you use the underscore:
Click for copyable input
But when you call a static method in such a class, the hierarchical context name is symbolic, so you must convert the underscore to U.
Click for copyable input
The same rule applies to method and field names. To refer to such names in code, use the U. Here is how to call a property named Some_Property.
In[1]:=
Click for copyable input

Getting Information About Types and Objects

NETTypeInfo

It is often convenient to be able to quickly display information about the methods, properties, fields, and so on that exist in a given .NET type. .NET/Link provides the NETTypeInfo function to obtain this information.
NETTypeInfo[typeName]print information about all the members in the given type
NETTypeInfo[typeName,members]print information about just the desired types of members in the given type
NETTypeInfo[typeName,members,"pat"]print information about the desired types of members whose names match a string pattern
NETTypeInfo[obj]print information about all the members in the object's type
NETTypeInfo[NETAssembly]print information about all the types in the given assembly

Getting information about types and objects.

NETTypeInfo will load the type if it has not already been loaded.
This will display a lot of information about the Process class.
Click for copyable input
The second argument to NETTypeInfo is an optional list of the members you want to see displayed. The possible values are "Type" (gives general info about the type itself), "Constructors", "Methods", "Properties", "Fields", and "Events". This will show just the properties and methods.
Click for copyable input
This will show just properties with names that begin with "Peak".
Click for copyable input
The default behavior is to display the members in C# syntax. If you want to see them in Visual Basic .NET syntax, use the LanguageSyntax option.
Click for copyable input
option name
default value
LanguageSyntax"CSharp"the language syntax in which output should be formatted must be "CSharp" or "VisualBasic"
InheritedTruewhether to include inherited members
IgnoreCaseFalsewhether to ignore case in matching names to a string pattern

Options to NETTypeInfo.

NETTypeInfo is also useful for seeing what types are in an assembly. To investigate an assembly, pass a NETAssembly expression as the first argument. The easiest way to get a NETAssembly expression is to call LoadNETAssembly (even if the assembly is already loaded). The following line will show a lot of types.
Click for copyable input
When acting on a NETAssembly, the second argument to NETTypeInfo is an optional list of the types you want to see displayed. The possible values are "Classes", "Interfaces", "Structures", "Delegates", and "Enums". This will show just the classes and interfaces with the word "Data" in their names.
Click for copyable input

Other Useful Functions

NETObjectQ[expr]return True if expr is a valid reference to a .NET object, False otherwise
InstanceOf[obj,type]return True if this object is an instance of type, False otherwise
GetTypeObject[NETType]return the Type object corresponding to a NETType expression
GetAssemblyObject[NETAssembly]return the Assembly object corresponding to a NETAssembly expression

Utility functions for objects and types.

NETObjectQ is convenient when you need to test whether an expression is a .NET object reference. It is often used as a pattern test in function definitions.
Click for copyable input
.NET/Link uses special expressions with heads NETType (returned by LoadNETType) and NETAssembly (returned by LoadNETAssembly) to represent .NET types and assemblies in Mathematica. As noted earlier, you can pass these expressions to functions that take types or assemblies as arguments (such as NETNew). There are times when you might want not a NETType expression, but an actual .NET Type object reference for a given type, and likewise for an assembly. You can use GetTypeObject to get the Type object corresponding to a NETType expression, and GetAssemblyObject to get the .NET Assembly object.
In[1]:=
Click for copyable input
Out[1]=
In[2]:=
Click for copyable input
Out[2]=
Notice above that the NETType expression is much more informative about what type it represents than the Type object. This is one reason why .NET/Link uses special NETType and NETAssembly expressions instead of just Type and Assembly objects.
Once you have a Type object, you can use methods and properties of the Type class to learn about it.
In[3]:=
Click for copyable input
Out[3]=
In[4]:=
Click for copyable input
Out[4]=

Reference Counts and Memory Management

Object References in Mathematica

In our earlier treatment of NETObject expressions we avoided discussing deeper issues such as reference counts and uniqueness. Every time a .NET object reference is returned to Mathematica, either as a result of a method or property or an explicit call to NETNew, .NET/Link looks to see if a reference to this object has been sent previously in this session. If not, it creates a NETObject expression in Mathematica and sets up a number of definitions for it. This is a comparatively time-consuming process. If this object has already been sent to Mathematica, in most cases .NET/Link simply creates a NETObject expression that is identical to the one created previously, which is a much faster operation.
There are some exceptions to this last rule, meaning that sometimes when an object is returned to Mathematica a new and different NETObject expression is created for it, even though this same object has previously been sent to Mathematica. Specifically, any time an object's hash value (as determined by the object's built-in GetHashCode() method) has changed since the last time it was seen in Mathematica, the NETObject expression created will be different. You do not really need to be concerned with the details of this, except to remember that Mathematica's SameQ function is not a valid way to compare NETObject expressions to decide whether they refer to the same object. You must use the SameObjectQ function.
SameObjectQ[obj1,obj2]return True if the NETObject expressions obj1 and obj2 refer to the same .NET object, return False otherwise

Comparing NETObject expressions.

Here is an example.
In[1]:=
Click for copyable input
Out[1]=
The variable pt refers to a .NET Point object. Now put it into a container so you can get it back out later.
In[2]:=
Click for copyable input
Now change the value of one of its coordinates. For a Point object, this changes its hash value.
In[4]:=
Click for copyable input
Now compare the NETObject expression given by pt and the NETObject expression created when you ask for the first element of the ArrayList to be returned to Mathematica. Even though these are both references to the same .NET object, the NETObject expressions are different. Recall that the ArrayList class defines an indexer (in C# terminology), so you can use the [] notation to refer to an element by index.
In[5]:=
Click for copyable input
Out[5]=
Because you cannot use SameQ (SameQ) to decide whether two object references in Mathematica refer to the same .NET object, .NET/Link provides the SameObjectQ function for this purpose.
In[6]:=
Click for copyable input
Out[6]=
You may be wondering why the SameObjectQ function is useful. Can't you just call an object's Equals() method? It certainly gives the correct result for this example.
In[7]:=
Click for copyable input
Out[7]=
The problem with this technique is that Equals() does not always compare object references. Any class is free to override Equals() to provide any desired behavior for comparing two objects of that class. Some classes make Equals() compare the "contents" of the objects, such as the String class, which uses it for string comparison. The function that provides the correct test is the static method ReferenceEquals().
In[8]:=
Click for copyable input
Out[8]=
You can think of SameObjectQ as a convenience function that does the same thing as explicitly calling ReferenceEquals().
In an unusual case where you need to compare object references for equality a very large number of times, the slowness of SameObjectQ compared to SameQ could become an issue. The only thing that could cause two NETObject expressions that refer to the exact same .NET object to not be SameQ is if the hash value of the object changed between the times that the two NETObject expressions were created. If you know this has not happened, you can safely use SameQ to test whether they refer to the same object.

ReleaseNETObject

The .NET runtime has a built-in facility called "garbage collection" for freeing up memory occupied by objects that are no longer in use by a program. Objects become eligible for garbage collection when no references to them exist anywhere, except perhaps in other objects that are also unreferenced. When an object is returned to Mathematica, either as a result of a call to NETNew or as the return value of a method or property, the .NET/Link code holds a special reference to the object on the .NET side to ensure that it cannot be garbage-collected while it is in use by Mathematica. If you know that you no longer need to use a given .NET object in your Mathematica session, you can explicitly tell .NET/Link to release its reference. The function that does this is ReleaseNETObject. In addition to releasing the Mathematica-specific reference in .NET, ReleaseNETObject clears out internal definitions that were created in Mathematica for the object. Any subsequent attempt to use this object in Mathematica will fail.
In[9]:=
Click for copyable input
Out[9]=
Now tell .NET that you no longer need to use this object from Mathematica.
In[10]:=
Click for copyable input
It is now an error to refer to frm because the object's symbolic representation has been removed from the Mathematica session. This is what you see if you try to use the released object.
In[11]:=
Click for copyable input
Out[11]=
ReleaseNETObject[obj]let .NET know that you are done using obj in Mathematica
NETBlock[expr]all novel .NET objects returned to Mathematica during the evaluation of expr will be released when expr finishes
BeginNETBlock[]all novel .NET objects returned to Mathematica between now and the matching EndNETBlock[] will be released
EndNETBlock[]release all novel objects seen since the matching BeginNETBlock[]
LoadedNETObjects[]return a list of all objects that are in use in Mathematica

Memory management functions.

Calling ReleaseNETObject will not necessarily cause the object to be garbage-collected. It is quite possible that other references to it exist in .NET. ReleaseNETObject does not tell .NET to throw the object away, only that it does not need to be kept around solely for Mathematica's sake.
An important fact about the references .NET/Link maintains for objects sent to Mathematica is that only one reference is kept for each object, no matter how many times it is returned to Mathematica. It is your responsibility to make sure that after you call ReleaseNETObject, you never attempt to use that object through any reference that might exist to it in your Mathematica session.
In[3]:=
Click for copyable input
If you call ReleaseNETObject[frm1], it is not the Mathematica symbol frm1 that is affected but the .NET object that frm1 refers to. Therefore, using frm2 is also an error (or any other way to refer to this same Form object).
Calling ReleaseNETObject is often unnecessary in casual use. If you are not making heavy use of .NET in your session, then you will not usually need to be concerned about keeping track of what objects may or may not be needed anymore—you can just let them pile up. There are times, though, when memory use in .NET will be important, and you may need the extra control that ReleaseNETObject provides.

NETBlock

ReleaseNETObject is provided mainly for developers who are writing code for others to use. Because it is not possible to predict how code will be used, developers should always be sure that their code cleans up any unnecessary references it creates. Probably the most useful function for this is NETBlock.
NETBlock automates the process of releasing objects encountered during the evaluation of an expression. Often, a Mathematica program will need to create some .NET objects with NETNew; operate with them, perhaps causing other objects to be returned to Mathematica as the results of method calls; and finally return some result such as a number or string. Every .NET object encountered by Mathematica during this operation is needed only during the lifetime of the program, much like the local variables provided in Mathematica by Block and Module, and in C#, C++, Java, and many other languages by block scoping constructs (e.g., {}). NETBlock allows you to mark a block of code as having the property that any new objects returned to Mathematica during the evaluation are to be treated as temporary and released when NETBlock finishes.
It is important to note that the preceding sentence said "new objects." NETBlock will not cause every object encountered during the evaluation to be released—only those that are being encountered for the first time. Objects that have already been seen by Mathematica will not be affected. This means that you do not have to worry that NETBlock will aggressively release an object that is not truly temporary to that evaluation.
It is not enough simply to call ReleaseNETObject on every object you create with NETNew, because many .NET methods and properties return objects. You might not be interested in these return values. You might never assign them to a named variable because they may be chained together with other calls (as in obj@ReturnsObject[]@Foo[]), but you still need to release them. Using NETBlock is an easy way to be sure that all novel objects are released when a block of code finishes.
NETBlock[expr] returns whatever expr returns.
Many .NET/Link Mathematica programs will have the following structure.
Click for copyable input
It is very common to write a function that creates a number of NETObject expressions and then returns one of them, the rest being temporary. To facilitate this, if the return value of a NETBlock is a single NETObject, it will not be released.
Click for copyable input
If you want more control over which objects are allowed to escape from a NETBlock, you can use the KeepNETObject function. Calling KeepNETObject on a single object or sequence of objects means they will not be released when the first enclosing NETBlock ends. If there is an outer enclosing NETBlock, the objects will be freed when it ends, however, so if you want the objects to escape a nested set of NETBlocks, you must call KeepNETObject at each level. Alternatively, you can call KeepNETObject[obj, Manual], where the Manual argument tells .NET/Link that the object should not be released by any enclosing NETBlocks. The only way such object will be released is if you manually call ReleaseNETObject on it.
KeepNETObject[obj1,obj2,...]do not release the given objects when the NETBlock ends
KeepNETObject[obj1,Manual]do not release the given object when any NETBlock ends

Keeping .NET objects after a NETBLock ends.

Here is an example that uses KeepNETObject to allow you to return a list of two objects without releasing them.
Click for copyable input
BeginNETBlock and EndNETBlock can be used to provide the same functionality as NETBlock across more than one evaluation. EndNETBlock releases all novel .NET objects returned to Mathematica since the previous matching BeginNETBlock. These functions are mainly of use during development, when you might want to set a mark in your session, do some work, and then release all novel objects returned to Mathematica since that point. BeginNETBlock and EndNETBlock can be nested. Every BeginNETBlock should have a matching EndNETBlock, although it is not a serious error to forget to call EndNETBlock, even if you have nested levels of them—you will only fail to release some objects.

LoadedNETObjects

LoadedNETObjects[] returns a list of all .NET objects that are currently referenced in Mathematica. This includes all objects explicitly created with NETNew and all those that were returned to Mathematica as the result of a .NET method or property. It does not include objects that have been released with ReleaseNETObject or through NETBlock. LoadedNETObjects is intended mainly for debugging. It is very useful to call it before and after some function you are working on. If the list grows, your function leaks references, and you need to examine its use of NETBlock and/or ReleaseNETObject.

Enums

Enumerations in .NET are a special kind of class, with each member of the enumeration represented as a static constant field in the class. Although the values of enumeration constants are integers, .NET/Link does not convert them into integers when they are returned to Mathematica. This is because enum values are probably only going to be passed back into some other .NET method—it is not likely that you will want to operate on them as integers in Mathematica. In this case, it is more meaningful to have them appear in Mathematica as objects of a class instead of just cryptic integer values.
Suppose you have a Button object btn that you want to anchor in a form so that it stays in a fixed position with respect to one or more edges as the form is resized. To do this, you set the button's Anchor property to a value from the AnchorStyles enum. First load the AnchorStyles type, as is always necessary when you want to access a static member of the type.
In[16]:=
Click for copyable input
Out[16]=
You refer to a member of this enum just like any other static field.
In[17]:=
Click for copyable input
Out[17]=
The enum is represented in Mathematica by a strongly typed object reference that is more meaningful to a programmer than the raw integer value, which happens to be 1. We can use the NETObjectToExpression function to convert the object reference to its integer value.
In[18]:=
Click for copyable input
Out[18]=
Now apply it to the button.
In[19]:=
Click for copyable input
For any argument that is typed as an enum, you can pass either an instance of the enum class or a raw integer value. This