.NET generic classes and methods can be specialized to specific types in MAXScript by using Type.MakeGenericType and MethodInfo.MakeGenericMethod(). These .NET methods create a type-specific version of a type or method. For example, if you run:
callSiteOps = (dotNetClass "System.Runtime.CompilerServices.CallSiteOps") showmethods callSiteOps
You will get:
.[static]AddRule <CallSite`1>site <T>rule .[static]<T>Bind <System.Runtime.CompilerServices.CallSiteBinder>binder <CallSite`1>site <System.Object[]>args .[static]ClearMatch <System.Runtime.CompilerServices.CallSite>site .[static]<System.Runtime.CompilerServices.CallSite`1[T]>CreateMatchmaker <CallSite`1>site .[static]<System.Boolean>Equals <System.Object>objA <System.Object>objB .[static]<T[]>GetCachedRules <RuleCache`1>cache .[static]<System.Boolean>GetMatch <System.Runtime.CompilerServices.CallSite>site .[static]<System.Runtime.CompilerServices.RuleCache`1[T]>GetRuleCache <CallSite`1>site .[static]<T[]>GetRules <CallSite`1>site .[static]MoveRule <RuleCache`1>cache <T>rule <System.Int32>i .[static]<System.Boolean>ReferenceEquals <System.Object>objA <System.Object>objB .[static]<System.Boolean>SetNotMatched <System.Runtime.CompilerServices.CallSite>site .[static]UpdateRules <CallSite`1>this <System.Int32>matched true
As you can see from the output, the line \[static\]AddRule <CallSite`1>site <T>rule indicates that the AddRule(<T>) method is a generic method. If you wanted a MAXScript version of this method that works with System.String, you would first get the method as a dotNetObject, and then specialize it so that <T> is System.String:
addRuleGeneric = getproperty callSiteOps "AddRule" asdotnetobject:true addRuleStringType = addRuleGeneric.MakeGenericMethod #(dotNetClass "System.String")
The AddRule() method takes 2 arguments, an instance of a templated class 'CallSite' and an instance of the specialized class . Looking at the CallSite documentation, you will see the method is documented as
AddRule<T>(CallSite<T>, T)
Adds a rule to the cache maintained on the dynamic call site.
In the MAXScript showmethods output, note the first arg is listed as <CallSite`1>site. This means that the argument is an instance of a generic class that is templated with a single Type (indicated by the `1 in the class name). Therefore in the documentation it is shown as CallSite<T>.
If the generic class was templated with two Types, it would be '2. An example of a class templated with two Types is:
System.Collections.Generic.Dictionary<TKey,TValue>
Which in MAXScript looks like:
d = dotnetclass "System.Collections.Generic.Dictionary`2" dotnet.showConstructors d
The showConstructors yields:
System.Collections.Generic.Dictionary`2() System.Collections.Generic.Dictionary`2 <IDictionary`2>dictionary System.Collections.Generic.Dictionary`2 <IEqualityComparer`1>comparer System.Collections.Generic.Dictionary`2 <System.Int32>capacity System.Collections.Generic.Dictionary`2 <System.Int32>capacity <IEqualityComparer`1>comparer System.Collections.Generic.Dictionary`2 <IDictionary`2>dictionary <IEqualityComparer`1>comparer
By using the following code, you create a instance of a dictionary where TKey is System.String and TValue is System.Int32:
genericType = dotnet.GetType "System.Collections.Generic.Dictionary`2" innerType1 = dotnet.GetType "System.String" innerType2 = dotnet.GetType "int" specificType = genericType.MakeGenericType #(innerType1, innerType2) theDict = (dotnetclass "System.Activator").CreateInstance specificType
This calls constructor:
System.Collections.Generic.Dictionary`2()
This code:
theDict = (dotnetclass "System.Activator").CreateInstance specificType #(32)
Calls the constructor:
System.Collections.Generic.Dictionary`2 <System.Int32>capacity
If the constructor took more than one argument, the additional arguments would be specified as additional elements in the array.