CLR Interoperability
You can write X++
statements for CLR interoperability using one of two methods: strong
typing or weak typing. We recommend that you use strong typing because
it is type-safe and less error-prone than weak typing, and it results in
code that is easier to read. The MorphX IDE also provides IntelliSense
as you type.
The examples in this section assume that you have added the .NET System.Xml assembly to the AOT references node. The programs are somewhat verbose because the compiler
supports only one method call per statement and because CLR types must
be identified by their fully qualified name. For example, the expression
System.Xml.XmlDocument is the fully qualified type name for the .NET Framework XML document type.
Caution
X++ is case-sensitive when referring to CLR types! |
The
following example demonstrates strongly typed CLR interoperability with
implicit type conversions from Dynamics AX strings to CLR strings in the
string assignment statements and shows how CLR exceptions are caught in
X++.
static void myJob(Args _args) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); System.Xml.XmlElement rootElement; System.Xml.XmlElement headElement; System.Xml.XmlElement docElement; System.String xml; System.String docStr = "Document"; System.String headStr = "Head"; System.Exception ex; str errorMessage; ; try { rootElement = doc.CreateElement(docStr); doc.AppendChild(rootElement); headElement = doc.CreateElement(headStr); docElement = doc.get_DocumentElement(); docElement.AppendChild(headElement); xml = doc.get_OuterXml(); print ClrInterop::getAnyTypeForObject(xml); pause; } catch(Exception::CLRError) { ex = ClrInterop::getLastException(); if( ex ) { errorMessage = ex.get_Message(); info( errorMessage ); } } }
|
The following example illustrates how static CLR methods are invoked by using the X++ static method accessor::.
static void myJob(Args _args) { System.Guid g = System.Guid::NewGuid(); }
|
Dynamics AX 2009 supports CLR arrays. The following example illustrates this new capability.
static void myJob(Args _args) { System.Int32 [] myArray = new System.Int32[100](); ; myArray.SetValue(1000, 0); print myArray.GetValue(0); }
|
Another new
capability in Dynamics AX 2009 is the support for passing parameters by
reference to CLR methods. Changes the called method makes to the
parameter also change the caller variable’s value. When non object type
variables are passed by reference, they are wrapped temporarily in an
object. This operation is often termed boxing and is illustrated in the following example.
static void myJob(Args _args) { int myVar = 5; ; MyNamespace.MyMath::Increment(byref myVar); print myVar; // prints 6 }
|
The called method could be implemented in C# like this.
// Notice: This example is C# code static public void Increment(ref int value) { value++; }
|
Note
Passing parameters by reference is supported only for CLR methods, not for X++ methods. |
The second method of
writing X++ statements for CLR uses weak typing. In the following
example, CLR types that perform the same steps as in the first CLR
interoperability example are shown. In this case, however, all
references are validated at run time, and all type conversions are
explicit.
static void myJob(Args _args) { ClrObject doc = new ClrObject("System.Xml.XmlDocument"); ClrObject docStr; ClrObject rootElement; ClrObject headElement; ClrObject docElement; ClrObject xml; ; docStr = ClrInterop::getObjectForAnyType("Document"); rootElement = doc.CreateElement(docStr); doc.AppendChild(rootElement); headElement = doc.CreateElement("Head"); docElement = doc.get_DocumentElement(); docElement.AppendChild(headElement); xml = doc.get_OuterXml(); print ClrInterop::getAnyTypeForObject(xml); pause; }
|
The first statement
in the preceding example demonstrates the use of a static method to
convert between X++ primitive types and CLR objects. The print statement shows the reverse, converting CLR value types to X++ primitive types. Table 9 lists the value type conversions that Dynamics AX supports.
Table 9. Type Conversions Supported in Dynamics AX
CLR Type | Dynamics AX Type |
---|
Byte, SByte, Int16, UInt16, Int32 | Int |
Byte, SByte, Int16, UInt16, Int32, Uint32, Int64 | Int64 |
DateTime | Utcdatetime |
Double, Single | Real |
Guid | Guid |
String | Str |
| |
Dynamics AX Type | CLR Type |
int | Int32, Int64 |
int64 | Int64 |
utcdatetime | DateTime |
real | Single, Double |
guid | Guid |
str | String |
The preceding code example also demonstrates the X++ method syntax used to access CLR object properties, such as get_DocumentElement. The CLR supports several operators that are not supported in X++. Table 10 lists the supported CLR operators and the alternative method syntax.
Table 10. CLR Operators and Methods
CLR Operators | CLR Methods |
---|
Property operators | get_<property>, set_<property> |
Index operators | get_Item,
set_Item |
Math operators | op_<operation>(arguments) |
The following features of CLR can’t be used with X++: