Friday, June 16, 2017

COLLECTION CLASSES : ARRAYS : MAPS: LIST:STRUCT: Microsoft Dynamics AX :MICROSOFT DYNAMICS 365:DYNAMICS AX 2012 X++

Collection Classes in Microsoft Dynamics AX

The X++ language syntax provides two compound types: arrays and containers. They are useful for aggregating values of simpler types. However, you cannot store objects in arrays or containers. The Microsoft Dynamics AX collection classes have been designed for storing objects. The classes are implemented in C++ to achieve the maximum performance (they are system classes).
Note
Collection classes were formerly called Foundation classes.

Collection Classes

The collection classes are shown in the following table.
Class
Description
Array
Similar to the X++ language array type except that it can hold values of any single type, including objects and records. Objects are accessed in a specific order.
For more information, see X++, C# Comparison: Array Syntax.
List
Contains elements that are accessed sequentially.
Unlike the Array class, the List class provides an addStart method.
As with the Set class, the List class provides methods getEnumerator and getIterator. You can use an iterator to insert and delete items from a List object.
Map
Associates a key value with another value.
Set
Holds values of any single type. Values are not stored in the sequence they are added. Instead, the Set object stores them in a manner that optimizes performance for the in method.
When you add a value to a Set object which is already storing that same value, the add attempt is ignored by the Set object.
Unlike the Array class, the Set class provides the methods in and remove.
Struct
Can contain values of more than one type. Used to group information about a specific entity.

Types Stored in Collections

The constructor for each collection class, except Struct, takes in a parameter value that is an element of the Types system enum. The collection instance can store items of that type only.
The Types::AnyType enum element is a special case and it cannot be used to construct a usable collection object, such as a Set object.
The null value cannot be stored as an element in a Set object. And null cannot be a key in a Map object.

Do Not Change Elements During Iteration

You can iterate through an X++ collection object with an iterator or enumerator. Here are typical examples of how you can obtain an iterator:
·         new MapIterator(myMap)
·         myMap.getEnumerator()
For Set objects, if any elements are added or removed after an iterator is created, the iterator instance can no longer be used to read from or step through the collection.
For Map objects, element removals invalidate the iterator just as for Set objects. However in Microsoft Dynamics AX 2012, a MapIterator object remains valid even after a call to the Map.insert method. This is true whether the key is new, or whether the key already exists and only the value is actually being updated in the Map element. X++ code that calls Map.insert and relies on the iterator object remaining valid might fail if run as .NET Framework CIL.
For more information, browse to the MSDN blogs and search for the X++ blog post titled Changes to the Collection Classes in Dynamics.

Extend a Collection Class

You can use the collection classes to form more complex classes. For example, a stack might easily be implemented by using a list where the elements are always added to the start of the list. The newest element then occupies the top of the stack.
You can also extend the collection classes. For example, you might extend the List class to create a list of customer records where the operations could be made type safe. The derived collection class would accept only customer records, not just any record.


The following example creates an array of classes and adds three query objects to the array.
X++
{
    Array oarray = new Array (Types::Class);

    oarray.value(1, new query());
    oarray.value(2, new query());
    oarray.value(4, new query()); 
    print oarray.toString();
    print oarray.definitionString();
    pause;
}


The following example creates a list of integers and prints out a description of the list and the values that it contains.
X++
{
    // Create a list of integers
    List il = new List(Types::Integer);
 
    // Add some elements to the list
    il.addEnd(1);
    il.addEnd(2);
    il.addStart(3);
 
    // Print a description of the list
    print il.definitionString();
    print il.toString();
    pause;
}

X++
{
    Map example;
 
    Map invertMap(map _mapToInvert)
    {
        MapEnumerator en;
        Map result =  new Map(
            _mapToInvert.valueType(),
            _mapToInvert.keyType());
 
        if (_mapToInvert.keySet().elements() 
            != _mapToInvert.valueSet().elements())
        {
            return null;
        }
        en = new MapEnumerator(_mapToInvert);
        while (en.moveNext())
        {
            result.insert(en.currentValue(), en.currentKey());
        }
        return result;
    }
 
    ;
 
    // Fill in a few values.
    example = new Map(Types::Integer, Types::String);
    example.insert (1, "one");
    example.insert (2, "two");
 
    print invertMap(example).toString();
    pause;
 
    // Now two keys (2 and 3) map to the same value
    // so can't create inverse map
    example.insert (3, "two");
    if (!invertMap(example))
    {
        print "Could not create the map";
    }
    pause;
}

The following example checks whether any of the values in one set, the noConfigs set, are found in a second set, the yesConfigs set. If they are, they are removed from the yesConfigs set.
X++
Set             noConfigs;
Set             yesConfigs;
ConfigId        configId;
SetEnumerator   se;
;
 
se = noConfigs.getEnumerator();
while (se.moveNext())
{
    configId    = se.current();
    if (yesConfigs.in(configId))
    {
        yesConfigs.remove(configId);
    }
}


The following example creates a struct with two items and then assigns values to those items. A new item is then added by using the Struct.addmethod; the data type of the item is inferred from the value assigned to it. The struct is then packed into a container and used to create a new struct, a copy of the original struct.
X++
{
    Struct s = new struct ("int age; str name");
    Struct copy;
    container c;
    int i;
    
    // Add values to the items
    s.value("age", 25);
    s.value("name", "Jane Dow");
 
  // Add a new item; data type is inferred from value
    s.add("Shoesize", 45);
 
    // Print the definition of the struct
    print s.definitionString();
 
    // Prints the type and name of all items in the struct
    for (i =  1;   i <= s.fields();i++)
    {
         print s.fieldType(i), " ", s.fieldName(i);
    } 
 
    // Pack the struct into a container and restore it into copy
    c = s.pack();
    copy = Struct::create(c);
    print copy.definitionString();
    pause;
}



No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...