DOBON.NET DOBON.NETプログラミング掲示板過去ログ

typeofで取得できた型にキャスト

環境/言語:[Windows XP Pro / C# 2005]
分類:[.NET]

いつもお世話になっております。

今回お聞きしたいのは、typeof、またはGetTypeなどのType取得メソッドで取得できたTypeに、キャストする方法です。

たとえば以下のようにTypeを取得します。

System.Type type = typeof(int);

上記で取得したTypeに変換してデータをキャストしたいのですが、
何か方法はあるでしょうか?

もしご存知の方がいらっしゃいましたら、ご教授下さい。
よろしくお願いいたします。

以上
意味がありません。


もっと詳しく何をしたいのかお書きになれば、何らかの解決を提示できるかもしれません。
2007/09/22(Sat) 16:06:25 編集(投稿者)

> もっと詳しく何をしたいのかお書きになれば、何らかの解決を提示できるかもしれません。

わかりにくかったようで申し訳ありません。
もう少し具体的に何をしたいかを説明いたしますと。
以下のコードのようになります。

例)

// DataTableの作成(CreateDataTableメソッドにて、カラムの設定なども行っておりますが、データは入っておりません)
DataTable dt = CreateDataTable();

// 各行の各カラムにデータを設定

DataRow dr = dt.NewRow();
for(int i; i < dt.Columns.Count; i++)
{
Type type = dt.Columns[i].GetType;
dr[dt.Columns[i].ColumnName] = i; // ※1
}

dt.Rows.Add(dr);

上記の※1で適切な型へと変換を行い、データを設定したいのです。
ただし、当然キャストエラーになるような場合はエラーでかまいません。
例)
string hoge1 = "テスト文字列";
int hoge2 = int.Parse(hoge1);

以上となります。
■No20549に返信(じゅでさんの記事)
> 2007/09/22(Sat) 16:06:25 編集(投稿者)
>
>>もっと詳しく何をしたいのかお書きになれば、何らかの解決を提示できるかもしれません。
>
> わかりにくかったようで申し訳ありません。
> もう少し具体的に何をしたいかを説明いたしますと。
> 以下のコードのようになります。
>
> 例)
>
> // DataTableの作成(CreateDataTableメソッドにて、カラムの設定なども行っておりますが、データは入っておりません)
> DataTable dt = CreateDataTable();
>
> // 各行の各カラムにデータを設定
>
> DataRow dr = dt.NewRow();
> for(int i; i < dt.Columns.Count; i++)
> {
> Type type = dt.Columns[i].GetType;
> dr[dt.Columns[i].ColumnName] = i; // ※1
> }
>
> dt.Rows.Add(dr);
>
> 上記の※1で適切な型へと変換を行い、データを設定したいのです。
> ただし、当然キャストエラーになるような場合はエラーでかまいません。
> 例)
> string hoge1 = "テスト文字列";
> int hoge2 = int.Parse(hoge1);
>
> 以上となります。

Type さえわかればリフレクションで Parse メソッドなどは呼び出すことはできますが、そもそもこれはキャストとは非なるものです。
こういったところから本質的にやりたいことが未だに見えてきません。

また Parse メソッドに限定して言えば、このメソッドを実装していると保証できる Interface はなく基本型に限定されます。
2007/09/22(Sat) 23:13:30 編集(投稿者)
2007/09/22(Sat) 22:58:53 編集(投稿者)
2007/09/22(Sat) 22:57:54 編集(投稿者)

■No20551に返信(じゃんぬねっとさんの記事)
> Type さえわかればリフレクションで Parse メソッドなどは呼び出すことはできますが、そもそもこれはキャストとは非なるものです。
> こういったところから本質的にやりたいことが未だに見えてきません。
>
> また Parse メソッドに限定して言えば、このメソッドを実装していると保証できる Interface はなく基本型に限定されます。

申し訳ありません。私の知識不足です。
やりたい事は、nUnitのテストデータを外部定義しておき、
読み込んだ値を適宜必要とされるメソッドのパラメータや
データテーブルのテスト値として設定する事です。
当然、テスト用の値として、適宜型を変更していかなければならないので、
キャストとして考えておりましたが、このような型変換をなんと表現するのか
言葉がわからずに、わかりにくいものになってしまいました。
申し訳ありません。

本題です。
リフレクションについては、メソッドやフィールドの取得などで使用していましたが、
メソッドを実行するInvokeメソッドにて、オブジェクトの配列をパラメータとして、指定する部分をみて
Typeさえわかれば、型をキャストして外部定義ファイルを読み込んで
使えるのではないかと思い至ったのが一番最初です。
そこで、Typeを判定して、型を変換する方法は無いだろうかと調べてみたのですが、
なかなか見つからないので、質問させていただきました。

以上が今私が理解している限りで、説明できる部分となるのですが、
まだわかりにくい部分がありましたら、私の知識の及ぶ範囲で、説明を追加いたします。

#System.Reflectionで試した事は無いですが、Parseメソッドを実装していない、自分自身で作成したクラスを引数にする事が可能なのであれば、
やりたい事はもっと違うものになるのでしょうか?


追記
string buff = "0001";
Type type = dt.Columns[0].DataType;
// 間違い
//System.Reflection.MethodInfo mi = type.GetMethod("Parse", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags);
// これ?
System.Reflection.MethodInfo mi =
type.GetMethod("Parse", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

としたまでは良いのですが、戻り値がInvokeの戻り値がobject型である事をすっかりと
失念しておりました。

もう少し調べてみます
> 追記
> string buff = "0001";
> Type type = dt.Columns[0].DataType;
> // 間違い
> //System.Reflection.MethodInfo mi = type.GetMethod("Parse", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags);
> // これ?
> System.Reflection.MethodInfo mi =
> type.GetMethod("Parse", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
>
> としたまでは良いのですが、戻り値がInvokeの戻り値がobject型である事をすっかりと
> 失念しておりました。
>
> もう少し調べてみます

object型である事は置いておいて、miの参照がnullになった為、GetMethodsで
メソッドの一覧を取得しようとしたら、0件でした。
どうにもパラメータの指定なり、そもそも"Parse"メソッドをこのようにして
呼び出す事が間違っているのか、わかりません。
もう少し調べてみますが、どなたかお詳しい方、お時間を頂く事になってしまいますが、
ご教授いただけないでしょうか。

よろしくお願いいたします。

以上
2007/09/23(Sun) 00:08:26 編集(投稿者)

原因が判明いたしました。
Typeがstringでした。申し訳ございません。
本当に申し訳ありませんでした。

以下がサンプル的なコードです。
ここからまたまたかなりかわってくるでしょうが、
何かのお役に立てば・・・(汚いコードですいません・・・たたない可能性のほうが高いですね)

ご協力頂いた方々、ありがとうございました。


public void CreateTestData(DataTable dt, int count)
{
for (int i = 0; i < count; i++)
{
DataRow dr = dt.NewRow();

for (int j = 0; j < dt.Columns.Count; j++)
{
string buff = i.ToString() + j.ToString();
Type type = dt.Columns[j].DataType;

if (type.Name != typeof(string).Name)
{
System.Reflection.MethodInfo[] miList = type.GetMethods();
foreach (System.Reflection.MethodInfo mi in miList)
{
string[] name = mi.ToString().Split(' ');
if (name[1] == "Parse(System.String)") // ここを何とかしたい
{
dr[d.Columns[j].ColumnName] = mi.Invoke(type, new object[] { (object)buff });
}
}
}
else
{
dr[dt.Columns[j].ColumnName] = buff;
}
}

dt.Rows.Add(dr);
}
}

追記

解決済み入れ忘れ。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板