この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。
GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) メソッドのオーバーロードとそれに関連するオーバーロード (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) および GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) を使用して、GetType メソッドのデフォルトの実装をより柔軟な実装に置き換えます。 型名とそれを含むアセンブリ名を解決する独自のメソッドを提供することで、以下を実行できます。
- 型がどのバージョンのアセンブリからロードされるかを制御します。
- アセンブリ名を含まない型名を探す別の場所を指定します。
- 部分アセンブリ名を使用してアセンブリをロードします。
- 共通言語ランタイム (CLR) が作成していない System.Type のサブクラスを返します。
たとえば、バージョン トレラントなシリアル化では、この方法で、部分的な名前を使って「最適な」アセンブリを検索することができます。 GetType メソッドの他のオーバーロードには、バージョン番号を含むアセンブリ修飾された型名が必要です。
型システムの代替実装は、CLR が作成しない System.Type のサブクラスを返す場合があります。GetType メソッドの他のオーバーロードによって返されるすべての型は、ランタイム型です。
使用に関する注記
このメソッドのオーバーロードとそれに関連するオーバーロードは、typeName
を型名とアセンブリ名に解析し、その名前を解決します。 型名はアセンブリのコンテキストで解決されなければならないため、アセンブリ名の解決は型名の解決よりも先に行われます。
注
アセンブリ修飾型名の概念に精通していないない場合は、「AssemblyQualifiedName プロパティ」を参照してください。
typeName
がアセンブリ修飾名ではない場合、アセンブリの解決は省略されます。 未修飾の型名は、mscorlib.dll/System.Private.CoreLib.dll たは現在実行中のアセンブリのコンテキストで解決できます。また、オプションで typeResolver
パラメーターにアセンブリを指定することもできます。 さまざまな種類の名前解決のためにアセンブリ名を含むか省略するかの効果は、「混合名前解決」セクションにテーブルとして表示されます。
一般的な使用上の注意:
不明な発信者または信頼できない発信者からのメソッドを
assemblyResolver
またはtypeResolver
に渡さないでください。 指定したメソッドまたは使い慣れているメソッドだけを使用してください。注意事項
不明な発信者または信頼できない発信者からのメソッドを使用すると、悪意のあるコードによる特権の昇格につながる場合があります。
assemblyResolver
やtypeResolver
パラメーターを省略すると、throwOnError
パラメーター値が、デフォルトの解決を行うメソッドに渡されます。throwOnError
がtrue
の場合、TypeLoadException がtypeResolver
とnull
を返す際または、FileNotFoundException がassemblyResolver
を返す際、このメソッドは、null
をスローします。このメソッドは、
assemblyResolver
とtypeResolver
がスロー下例外を取得しません。 リゾルバ メソッドによってスローされる例外は、すべてユーザーの責任です。
アセンブリの解決
assemblyResolver
メソッドは AssemblyName オブジェクトを受け取り、このオブジェクトは typeName
に含まれる文字列アセンブリ名を解析して生成されます。
typeName
にアセンブリ名が含まれていない場合、assemblyResolver
は呼び出されず、null
は、typeResolver
に渡されます。
assemblyResolver
が提供されない場合は、標準のアセンブリ プローブがアセンブリの位置を特定するために使用されます。
assemblyResolver
が指定された場合、GetType メソッドは、標準プローブを行いません。この場合、assemblyResolver
が、渡されたすべてのアセンブリを処理できるようにする必要があります。
アセンブリを解決できない場合、assemblyResolver
メソッドは、null
を返します。
assemblyResolver
が null
を返す場合、typeResolver
は、呼び出されず、後続の処理が発生し、さらに、throwOnError
が true
の場合は、FileNotFoundException がスローされます。
AssemblyName に渡された assemblyResolver
が部分名の場合、1 つ以上のその部分が null
になります。 たとえば、バージョンが無い場合は、Version プロパティが null
になります。
Version プロパティ、CultureInfo プロパティおよび GetPublicKeyToken メソッドのすべてが null
を返す場合、アセンブリのシンプルな名前のみが指定されます。
assemblyResolver
メソッドは、アセンブリ名のすべての部分に使用できるか、それを無視できます。
異なるアセンブリ解決オプションの効果は、「混合名前解決」セクションで、単純型名とアセンブリ修飾型名についてテーブルとして表示されます。
型の解決
typeName
は、アセンブリ名を指定せず、常に typeResolver
を呼び出します。
typeName
は、アセンブリ名を指定し、アセンブリ名が正常に解決されると、typeResolver
を呼び出します。
assemblyResolver
または標準アセンブリ プローブが null
を返した場合、typeResolver
は呼び出されません。
typeResolver
メソッドは、3 つの引数を受信します。
-
null
にアセンブリ名が含まれていない場合は、検索するアセンブリ、またはtypeName
。 - 単純型の名前。 入れ子になった型の場合、これは一番外側に含まれる型です。 ジェネリック型の場合、これはジェネリック型の単純な名前です。
- 型名の大文字と小文字を無視する場合は
true
となるブール値。
これらの引数の使用方法は、実装によって決まります。 型を解決できない場合、typeResolver
メソッドは、null
を返します。
typeResolver
が null
を返した場合、throwOnError
は true
となり、この GetType のオーバーロードは、TypeLoadException をスローします。
異なる型解決オプションの効果は、「混合名前解決」セクションで、単純型名とアセンブリ修飾型名についてテーブルとして表示されます。
入れ子型を解決する
typeName
が入れ子型の場合、もっとも外側に含まれている型の名前が typeResolver
に渡されます。
typeResolver
がこの型を返す際、GetNestedType メソッドは、最も内側の入れ子型が解決されるまで再帰的に呼び出されます。
ジェネリック型を解決する
GetType は、ジェネリック型を解決するために再帰的に呼び出されます。まずジェネリック型を解決し、次にその型引数を解決します。 型引数がジェネリックの場合、GetType は再帰的に呼び出され、その型引数を解決します。
指定する assemblyResolver
と typeResolver
の組み合わせは、この再帰のすべてのレベルを解決できるものでなければなりません。 例えば、assemblyResolver
のロードを制御する MyAssembly
を指定したとします。 ジェネリック型 Dictionary<string, MyType>
(Visual Basicでは Dictionary(Of String, MyType)
) を解決したいとします。 次のようなジェネリック型名を渡すことができます。
"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"
MyType
が唯一のアセンブリ修飾型引数であることに気づきます。
Dictionary<TKey,TValue> と String のクラス名はアセンブリ修飾されません。
typeResolver
は null
と null
に対して Dictionary<TKey,TValue> を受け取りため、アセンブリまたは String のいずれかを処理できる必要があります。 その場合は、文字列を受け取る GetType メソッドのオーバーロードを呼び出すことで対処できます。これは、修飾されていない型名は両方ともmscorlib.dll/System.Private.CoreLib.dll にあるためです。
Type t = Type.GetType(test,
(aName) => aName.Name == "MyAssembly" ?
Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") : null,
(assem, name, ignore) => assem == null ?
Type.GetType(name, false, ignore) :
assem.GetType(name, false, ignore)
);
let t =
Type.GetType(test,
(fun aName ->
if aName.Name = "MyAssembly" then
Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
else null),
fun assem name ignr ->
if assem = null then
Type.GetType(name, false, ignr)
else
assem.GetType(name, false, ignr))
ディクショナリ型と文字列型はアセンブリ修飾されていないため、assemblyResolver
メソッドは呼び出されません。
ここで、System.String
の代わりに YourType
から YourAssembly
が最初のジェネリック引数の型になったとします。
"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"
このアセンブリは、mscorlib.dll/System.Private.CoreLib.dll でも現在実行中のアセンブリでもないため、アセンブリ修飾名なしで YourType
を解決することはできません。
assemblyResolve
は再帰的に呼び出されるため、このケースに対応できる必要があります。
null
以外のアセンブリに対して MyAssembly
を返す代わりに、提供された AssemblyName オブジェクトを使用してアセンブリのロードを実行するようになりました。
Type t2 = Type.GetType(test,
(aName) => aName.Name == "MyAssembly" ?
Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") :
Assembly.Load(aName),
(assem, name, ignore) => assem == null ?
Type.GetType(name, false, ignore) :
assem.GetType(name, false, ignore), true
);
let t2 =
Type.GetType(test,
(fun aName ->
if aName.Name = "MyAssembly" then
Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
else Assembly.Load aName),
(fun assem name ignr ->
if assem = null then
Type.GetType(name, false, ignr)
else
assem.GetType(name, false, ignr)), true)
特殊文字を使用して型名を解決する
アセンブリ修飾名には特別な意味を持つ文字があります。 単純型名にこれらの文字が含まれていると、単純型名がアセンブリ修飾名の一部である場合に、この文字によって解析エラーが発生します。 解析エラーを避けるには、アセンブリ修飾名を GetType メソッドに渡す前に、特殊文字をバックスラッシュでエスケープする必要があります。 たとえば、型の名前が Strange]Type
の場合、エスケープ文字は Strange\]Type
のように角括弧の前に追加する必要があります。
注
このような特殊文字を含む名前は Visual Basic または C# では作成できませんが、共通中間言語 (CIL) を使用するか、動的アセンブリを生成することで作成できます。
次の表は、型名の特殊文字を示しています。
キャラクター | 意味 |
---|---|
, (コンマ) |
アセンブリ修飾名の区切り文字。 |
[] (角括弧) |
サフィックス ペアの場合は配列型を示します。区切り文字ペアの場合は、ジェネリック引数リストとアセンブリ修飾名を囲みます。 |
& (アンパサンド) |
サフィックスとして、型が参照型であることを示します。 |
* (アスタリスク) |
サフィックスとして、型がポインター型であることを示します。 |
+ (プラス) |
入れ子型の区切り文字。 |
\ (バックスラッシュ) |
エスケープ文字。 |
AssemblyQualifiedName などのプロパティは、正しくエスケープされた文字列を返します。
GetType メソッドには正しくエスケープされた文字列を渡す必要があります。 次に、GetType メソッドは正しくエスケープされた名前を typeResolver
とデフォルトの型解決メソッドに渡します。 名前を typeResolver
内のエスケープされていない名前と比較する必要がある場合は、エスケープ文字を削除する必要があります。
混合名前解決
次の表は、assemblyResolver
の型名とアセンブリ名のすべての組み合わせについて、typeResolver
、typeName
、および既定の名前解決間の相互作用をまとめたものです。
型名の内容 | アセンブリ リゾルバ メソッド | 型リゾルバ メソッド | 結果 |
---|---|---|---|
型、アセンブリ | 無効 | 無効 | Type.GetType(String, Boolean, Boolean) メソッドのオーバーロードを呼び出すのと同じです。 |
型、アセンブリ | 提供の | 無効 |
assemblyResolver はアセンブリを返します。アセンブリを解決できない場合は null を返します。 アセンブリが解決された場合、Assembly.GetType(String, Boolean, Boolean) メソッド オーバーロードを使用してアセンブリから型がロードされます。それ以外の場合、型の解決は試行されません。 |
型、アセンブリ | 無効 | 提供の | アセンブリ名を AssemblyName オブジェクトに変換し、Assembly.Load(AssemblyName) メソッド オーバーロードを呼び出してアセンブリを取得するのと同じです。 アセンブリが解決された場合は typeResolver に渡されます。それ以外の場合は typeResolver は呼び出されず、型の解決はそれ以上試行されません。 |
型、アセンブリ | 提供の | 提供の |
assemblyResolver はアセンブリを返します。アセンブリを解決できない場合は null を返します。 アセンブリが解決された場合は typeResolver に渡されます。それ以外の場合は typeResolver は呼び出されず、型の解決はそれ以上試行されません。 |
種類 | null、指定 | 無効 |
Type.GetType(String, Boolean, Boolean) メソッドのオーバーロードを呼び出すのと同じです。 アセンブリ名が指定されていないため、mscorlib.dll/System.Private.CoreLib.dll と現在実行中のアセンブリのみが検索されます。
assemblyResolver が指定されていても無視されます。 |
種類 | null、指定 | 提供の |
typeResolver が呼び出され、null がアセンブリに渡されます。
typeResolver 目的のために読み込むアセンブリを含む、任意のアセンブリから型を指定します。
assemblyResolver が指定されていても無視されます。 |
集会 | null、指定 | null、指定 | アセンブリ名はアセンブリ修飾型名であるかのように解析されるため、FileLoadException がスローされます。 この結果、アセンブリ名が無効になります。 |
.NET