C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

配列にデータ型を入れてその後データ型名を取得したい /C#勉強中 (18/07/04(Wed) 13:09) #87837
Re[1]: 配列にデータ型を入れてその後データ型名を取得したい /Hongliang (18/07/04(Wed) 13:24) #87838
  └ Re[2]: 配列にデータ型を入れてその後データ型名を取得したい /C#勉強中 (18/07/04(Wed) 13:55) #87839
    ├ Re[3]: 配列にデータ型を入れてその後データ型名を取得したい /Hongliang (18/07/04(Wed) 15:19) #87841
    └ Re[3]: 配列にデータ型を入れてその後データ型名を取得したい /魔界の仮面弁士 (18/07/04(Wed) 15:31) #87842
      └ Re[4]: 配列にデータ型を入れてその後データ型名を取得したい /C#勉強中 (18/07/04(Wed) 17:52) #87843
        └ Re[5]: 配列にデータ型を入れてその後データ型名を取得したい /にゃるら (18/07/05(Thu) 09:25) #87847
          └ Re[6]: 配列にデータ型を入れてその後データ型名を取得したい /C#勉強中 (18/07/05(Thu) 11:51) #87848 解決済み


親記事 / ▼[ 87838 ]
■87837 / 親階層)  配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ C#勉強中 (1回)-(2018/07/04(Wed) 13:09:48)

分類:[C#] 

はじめまして。
C#勉強中のため、おかしな質問かもしれませんがよろしくおねがいします。

配列にデータ型を入れ、その後データ型名(System.〜)を取得したいのですが上手くいきません。

コードの書き方が正しいのか間違っているかさえ分かりませんが、
コード2では思った結果が得られています。

コード1のような書き方でコード2と同じ結果を得ることはできますか?
また、System.RuntimeType とは一体何ですか?

よろしくおねがいします。

<開発環境>
VisualStudio 2017 Community C#

<コード1>
Type[] t = new Type[3];
t[0] = typeof(Single);
t[1] = typeof(DateTime);
t[2] = typeof(string);

System.Diagnostics.Debug.Print(t[0].GetType().ToString());
System.Diagnostics.Debug.Print(t[1].GetType().ToString());
System.Diagnostics.Debug.Print(t[2].GetType().ToString());

実行結果
System.RuntimeType
System.RuntimeType
System.RuntimeType


<コード2>
string[] strAry = new string[3];
strAry[0] = "System.Single";
strAry[1] = "System.DateTime";
strAry[2] = "System.String";

System.Diagnostics.Debug.Print(Type.GetType(strAry[0]).ToString());
System.Diagnostics.Debug.Print(Type.GetType(strAry[1]).ToString());
System.Diagnostics.Debug.Print(Type.GetType(strAry[2]).ToString());

実行結果
System.Single
System.DateTime
System.String


[ □ Tree ] 返信 編集キー/

▲[ 87837 ] / ▼[ 87839 ]
■87838 / 1階層)  Re[1]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ Hongliang (657回)-(2018/07/04(Wed) 13:24:46)
> System.Diagnostics.Debug.Print(t[0].GetType().ToString());

t[0]は既に「Stringを指すTypeオブジェクト」が格納されています。
なので、t[0].ToString()すれば(FullNameプロパティの方が適切ですが)、想定されている文字列が出力されるでしょう。
Typeオブジェクトに対してGetType()すれば、取得できるのは「Typeを指すTypeオブジェクト」になります。

typeof()はType型オブジェクトを返しますが、Type型は派生可能であり、typeof()が返すのもTypeそのものではなくその派生クラスの可能性があります。
実行されている環境では、実体としてはType型の派生クラスであるRuntimeType型が返されているということです。
.GetType()はオブジェクト自身に自分の型を問い合わせるメソッドですので、変数の型であるTypeではなく、実際に自分の型であるRuntimeType(を指すTypeオブジェクト)を返しています。
[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87838 ] / ▼[ 87841 ] ▼[ 87842 ]
■87839 / 2階層)  Re[2]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ C#勉強中 (2回)-(2018/07/04(Wed) 13:55:05)
Hongliang さんご回答ありがとうございます。
教えていただいた方法で思った結果が得られました。
ありがとうございました。

System.Diagnostics.Debug.Print(t[0].FullName);

恐れ入りますが、
いただいた回答の内容で分からない点があるので教えてください。

>t[0]は既に「Stringを指すTypeオブジェクト」が格納されています。
 t[0]には Single型が入っているのではないのですか?

>typeof()はType型オブジェクトを返しますが、T
>ype型は派生可能であり、typeof()が返すのもTypeそのものではなくその派生クラスの可能性があります。

 実行されている環境によっては typeof(Single) や typeof(DateTime)
 のように書いても今回のような意図しない RuntimeType型 が返される時があるのですか?

 もし意図しない RuntimeType型が返されるのであれば、
 確実にType型を指定する方法はありますか?


よろしくおねがいします。


[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87839 ] / 返信無し
■87841 / 3階層)  Re[3]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ Hongliang (658回)-(2018/07/04(Wed) 15:19:42)
> >t[0]は既に「Stringを指すTypeオブジェクト」が格納されています。
>  t[0]には Single型が入っているのではないのですか?

変数に格納されるのは常にオブジェクトです。Single型というのは概念であってオブジェクトではありません。
「Singleという型を表現するデータ」を持つ「Type型のオブジェクト」が格納されているのです。
Type型ではなくString型で言うなら、
「"hoge"という文字列を表現するデータ」を持つ「String型のオブジェクト」が、String型の変数に格納されるのと同じです。

>  実行されている環境によっては typeof(Single) や typeof(DateTime)
>  のように書いても今回のような意図しない RuntimeType型 が返される時があるのですか?
>
>  もし意図しない RuntimeType型が返されるのであれば、
>  確実にType型を指定する方法はありますか?

「Type型を指定する」というのはどういう意味でしょうか。
typeof()が返すオブジェクトの型を、という意味なら、そんな方法はありませんしそうする意味も必要もありません。
常にType型オブジェクトとして扱えばいいだけです。
そもそもTypeクラスはabstractなので、実体がType型というオブジェクトは存在し得ないです。
[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87839 ] / ▼[ 87843 ]
■87842 / 3階層)  Re[3]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ 魔界の仮面弁士 (1736回)-(2018/07/04(Wed) 15:31:41)
No87839 (C#勉強中 さん) に返信
>> t[0]は既に「Stringを指すTypeオブジェクト」が格納されています。
>  t[0]には Single型が入っているのではないのですか?

t[2] の書き間違いかな…?

t[0] には Type クラスのインスタンスが入っています。これは System.Single 構造体の型を指しています。
t[1] には Type クラスのインスタンスが入っています。これは System.DateTime 構造体の型を指しています。
t[2] には Type クラスのインスタンスが入っています。これは System.String クラスの型を指しています。

t[0〜2].GetType() は Type クラスのインスタンスを返します。
これはいずれも、System.RuntimeType 構造体の型を指しています。


> 実行されている環境によっては typeof(Single) や typeof(DateTime)
> のように書いても今回のような意図しない RuntimeType型 が返される時があるのですか?

// t1, t2, t3 は同一インスタンス
Type t1 = Single.MaxValue.GetType();
Type t2 = typeof(Single);
Type t3 = Type.GetType("System.Single");

これらはいずれも「Type クラスのインスタンス」を返します。
このインスタンスは、常に『Single 構造体を表す型』です。


しかし最初の質問コードのように、
 Type t = [Type クラスのインスタンス].GetType();
とした場合は、「Type.GetType("System.RuntimeType")」が返されます。
[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87842 ] / ▼[ 87847 ]
■87843 / 4階層)  Re[4]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ C#勉強中 (4回)-(2018/07/04(Wed) 17:52:54)
Hongliang さん 魔界の仮面弁士 さん
ご回答ありがとうございます。

勉強不足で返信が遅くなりました。

>Type[] t = new Type[0];
>t[0] = typeof(Single);
>
>System.Diagnostics.Debug.Print(t[0].GetType().ToString());

最初の質問のように書くと、t[0] のSingle型インスタンスではなく、
Type型に対して GetType が行われたので System.RuntimeType が返された。

このような理解で良いでしょうか?

よろしくおねがいします。








[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87843 ] / ▼[ 87848 ]
■87847 / 5階層)  Re[5]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ にゃるら (30回)-(2018/07/05(Thu) 09:25:58)
2018/07/05(Thu) 09:30:46 編集(投稿者)

合ってるのではないでしょうか。


string str = "abc";
Type t = str.GetType();
Type r = t.GetType();

System.Diagnostics.Debug.Print(str.ToString());
System.Diagnostics.Debug.Print(t.ToString());
System.Diagnostics.Debug.Print(r.ToString());

strはstring型のインスタンス。
tはstrというオブジェクト(string型)の型情報」。
rはtというオブジェクト(System.Type型)の型情報。

となります。


[ 親 87837 / □ Tree ] 返信 編集キー/

▲[ 87847 ] / 返信無し
■87848 / 6階層)  Re[6]: 配列にデータ型を入れてその後データ型名を取得したい
□投稿者/ C#勉強中 (5回)-(2018/07/05(Thu) 11:51:43)
にゃるら さん
ご回答ありがとうございます。

おかげですっきりしました。
この件は解決済みとします。


皆様ありがとうございました。

解決済み
[ 親 87837 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -