C#のSystem.TypeとSystem.RuntimeTypeの違いは何ですか?


89

私は今日、いくつかのコンベンションテストを行おうとしていて、Assembly.GetTypes()何かに出くわしたときに、アセンブリ内のすべてのタイプを取得しようとしていました(を呼び出すことによって)。

System.RuntimeType:[First.Namespace.FirstClass]

そのタイプをと比較しようとするときはいつでもtypeof(FirstClass)、それらは等しくありません。そのためFirstClass、ジェネリックパラメーターとして含まれているすべての型を検索しようとしても、何も見つかりません。

違いは何だSystem.RuntimeTypeとはSystem.Type

私の問題を解決する方法はありますか?


6
発生している問題を示す小さなプログラムを提供できますか?
Eric Lippert 2011

私は行くつもりでしたが、すでに答えを得ました:P
エドガーゴンザレス

回答:


108

System.RuntimeTypeは、抽象基本クラスから派生した具象クラスSystem.Typeです。System.RuntimeTypeは公開されていないため、通常はとしてインスタンスに遭遇しますSystem.Type

オブジェクトの型を取得しようとして、GetType()そのオブジェクトを直接使用するのではなく、最初のオブジェクトの型を表す別のオブジェクトを誤って呼び出しようとすると、混乱が生じる可能性があります。次に、呼び出されたオブジェクトがタイプを表しているときType.ToString()に戻り"System.RuntimeType"ます。

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

たとえば、このブログ投稿では、誰かがデータベース内の列の型を取得しようとして、次のようなことを行っています。

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

valはすでにTypeオブジェクトであるため、val.GetType()はSystem.RuntimeTime、元の型オブジェクトを表すために使用される具象型であるため、型を表す別のTypeオブジェクトを返します。ブログの投稿では、元の型オブジェクトの型を取得するために、実際に必要なのは次の場合に、不要なリフレクションのトリックを示しています。

Type type = reader.GetFieldType(index) as Type;

したがって、Typeオブジェクトがを表すと報告している場合は、すでに取得しているタイプをSystem.RuntimeType誤って呼び出していないことを確認してくださいGetType()


最初のコードスニペットは、オブジェクトがのインスタンスであるかどうかのみをチェックしTypeます—を渡してもtrueを返しますtypeof(int)。2番目のコードスニペットは、比較のために動作しませんtypeof(string).GetType()typeof(Type)
Mark Cidade 2011

これはまさに私が探していたものです!Thomas Daneckerの投稿は見つかりましたが、Doogal Bellの投稿は見つかりませんでした
Edgar Gonzalez

1
@マークシダーデ。よく発見された、ありがとう。そのブログ投稿を引用することで私が紹介した混乱を解消できれば、より役立つように回答を修正してください。
Ergwun 2011

@Edgar Gonzalez:私が参照したそのブログ投稿は、実際にはかなり誤解を招くものでした。より良い情報については、私の更新された回答を参照してください。
Ergwun 2011

4

Thomas DaneckerによるSystem.TypeとSystem.RuntimeTypeの違いへの回答から:

System.Typeは抽象基本クラスです。CLRには、内部型System.RuntimeTypeでの具体的な実装があります。このため、typeof(string).GetType()はRuntimeTypeを返しますが、typeof(Type)は通常のTypeを返します。.Equalsメソッドを使用すると、実際には、falseを返すobject.ReferenceEqualsが実行されます。期待どおりの結果を得るには、type.IsInstanceOfType(element)を使用できます。要素が派生型の場合も、これはtrueを返します。正確な型を確認したい場合は、メソッドのfalseの戻り値が望ましい結果になります。checkType(arrayType、Type.GetType( "System.RuntimeType"))を使用してRuntimeTypeをチェックすることもできます。


1
「実際には」-文法の修正を取得できますか。これは全体の核心のようなものであり、意味がありません。
N73k

2

簡単に...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

私が今考えているのはSystem.Type、実行時のオブジェクト型要求の結果を表す型の基本型、つまりSystem.RuntimeType。したがって、のようにオブジェクトの型を要求すると、返さ"".GetType()れるインスタンスSystem.Typeはその子孫ですSystem.RuntimeType。実際、そうあるべきだと期待するtypeof(System.Type).GetType()必要がありSystem.RuntimeTypeますが、フレームワークは特にこれを防ぎます...対称性。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.