MSDyn365FO. How-to pass generic types to .Net method

There is a wonderful blog post about Generic types in X++. And as It says, the easiest way to work with generic types in X++ is to create .Net library and expose non-generic interface, because X++ compiler has lots of limitations.
However, if you really want to have some fun and stick to X++, it’s possible with a help of reflection.
Let’s say we have a C# class that accepts List<string[]> and we want to invoke it from X++:
public class Class1
{
public static string myMethod(List<string[]> list)
{
string res = string.Empty;
foreach (var array in list)
{
foreach (string s in array)
{
res += s;
}
}
return res;
}
}
We cannot simply declare:
var stringList = new System.Collections.Generic.List<String[]>();
Looks like X++ parser cannot handle “<” and “[” combination, as it gives “Invalid token ‘<‘. ” compile error.
Therefore, instead of 2 lines of code in C#:
var stringArrayList = new System.Collections.Generic.List<string[]> { new string[] { "a", "b", "c" } };
string res = Class1.myMethod(stringArrayList);
We need a bit more in X++:
System.String string;
//array we want to put into a list
System.String[] stringArray = new System.String[3]();
stringArray.SetValue('a', 0);
stringArray.SetValue('b', 1);
stringArray.SetValue('c', 2);
//Type[] array for MakeGenericType
System.Type[] typeParams = new System.Type[1]();
typeParams.SetValue(string.GetType().MakeArrayType(), 0);
//instantiate System.Collections.Generic.List<String[]>
System.Type listType = System.Type::GetType("System.Collections.Generic.List`1");
var constructedListType = listType.MakeGenericType(typeParams);
var stringArrayList = System.Activator::CreateInstance(constructedListType);
//invoke "Add" using reflection because we cannot cast it back to List<String[]>
var bindingFlags = BindingFlags::Instance | BindingFlags::Public;
System.Reflection.MethodInfo methodsInfo = constructedListType.GetMethod("Add", bindingFlags);
System.Object[] params = new System.Object[1]();
params.SetValue(stringArray, 0);
methodsInfo.Invoke(stringArrayList, params);
info(Class1::myMethod(stringArrayList));
X++ is lacking in .Net features and often it’s easier to create intermediate C# class library. However, as you can see, some limitations are caused by X++ compiler that could be overcome using reflection.
This was originally posted here.

Like
Report
*This post is locked for comments