dotNet 汎用クラス

.NET の汎用のクラスおよびメソッドは、Type.MakeGenericType および MethodInfo.MakeGenericMethod() を使用することで、MAXScript の特定のタイプの専用クラスおよびメソッドにすることができます。これらの .NET メソッドは、タイプまたはメソッドのタイプ固有のバージョンを作成します。たとえば、以下を実行するとします。

callSiteOps = (dotNetClass "System.Runtime.CompilerServices.CallSiteOps")
showmethods callSiteOps

次の結果が得られます。

.[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

出力からわかるように、行 \[static\]AddRule <CallSite`1>site <T>rule は AddRule(<T>) メソッドが汎用メソッドであることを示します。System.String と連携する、このメソッドの MAXScript バージョンが必要な場合は、このメソッドを dotNetObject として取得してから、<T> が System.String となるようにしてこのメソッドを専用メソッドにします。

addRuleGeneric = getproperty callSiteOps "AddRule" asdotnetobject:true
addRuleStringType = addRuleGeneric.MakeGenericMethod #(dotNetClass "System.String")

AddRule() メソッドは 2 つの引数を取ります。1 つはテンプレート化されたクラス「CallSite」のインスタンスで、もう 1 つは専用クラスのインスタンスです。CallSite のドキュメントを参照すると、このメソッドが次のように記述されています。

AddRule<T>(CallSite<T>, T)

動的呼び出しサイトで維持されているキャッシュにルールを追加します。

MAXScript showmethods の出力に、最初の引数が「<CallSite`1>site」と表示されていることに注目してください。つまり、この引数は、単一タイプを使用する、テンプレート化された汎用クラスのインスタンスです(単一タイプであることは、クラス名に「1」があることで示されます)。したがって、このクラスはドキュメント内では CallSite<T> と示されています。

汎用クラスが 2 つのタイプを使用してテンプレート化されている場合は、これが「2」になります。2 つのタイプを使用してテンプレート化されたクラスの例を次に示します。

System.Collections.Generic.Dictionary<TKey,TValue>

MAXScript では次のようになります。

d = dotnetclass "System.Collections.Generic.Dictionary`2"
dotnet.showConstructors d

showConstructors は以下を生成します。

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

次のコードを使用して、ディクショナリのインスタンスを作成します。ここで、TKey は System.String、TValue は 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

このコードは次のコンストラクタを呼び出します。

System.Collections.Generic.Dictionary`2()

次のコードがあるとします。

theDict = (dotnetclass "System.Activator").CreateInstance specificType #(32)

このコードは次のコンストラクタを呼び出します。

System.Collections.Generic.Dictionary`2 <System.Int32>capacity

コンストラクタが複数の引数を取った場合、追加の引数は配列内の追加要素として指定されます。