質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1503閲覧

【C#】ジェネリクスにクラス名をそのまま渡す以外の方法で実行したい

masahase

総合スコア26

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2021/06/16 07:09

問題点

ジェネリクスにクラス名をそのまま渡す以外の方法で実行したい

詳細

まずやりたい事の例は、下記のCreaterクラス内のcrateメソッドは他にあるフィールド参照用クラスを用いてファイル(ScriptableObject)を作成します。

現在は1つのクラスのみの書き出しに対応していますが、フィールド参照用クラスは複数作成される予定なので複数のクラスに対応したいです。

その為、ジェネリクスを用いてStarterクラスから全てのフィールド参照用クラス型をCreaterクラスに渡して実行したいのですがそもそも渡せない状態です。

尚、参照用クラスのファイル名は参照用クラスの為のディレクトリが決まっているのでそのディレクトリ内ファイル名を取得しループで渡すつもりでした。

これは仕様でそもそもこう言った事はできないのでしょうか?

C#

1public class Creater<T> 2{ 3 public void create(T t) 4 { 5 # 何か処理 6 } 7} 8 9 10public class Starter 11{ 12 # 下記の方法は全てエラーです 13 # 試した事1:オブジェクト名を文字列で入れる 14  string str= "Creater"; 15 Creater<str> creater01 = new Creater<str>(); 16 17  # 試した事2:オブジェクト名をからオブジェクトを生成して代入 18 Type type = Type.GetType("Creater"); 19  object obj = Activator.CreateInstance(type); 20 Creater<obj> creater02 = new Creater<obj>(); 21} 22 23

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

いまいち何がしたいのかよく判りませんが、やりたいのはこういうこと?
ジェネリックなコレクションのインスタンスをリフレクションで生成する

投稿2021/06/16 07:22

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masahase

2021/06/16 13:20

返信ありがとうございます。記載していませんでしたが、Creater<T>のTに入るのはフィールド参照用クラスが型として入ります。 また、処理に必要なフィールド参照クラスは上記双方のクラス内で直接記述する訳ではなく、Starterクラスで指定のディレクトリからフィールド参照クラスの一覧を取得しその情報を元に型を指定したいのです。 持っている情報は、Creater<T>に必要なフィールド参照用クラスのディレクトリのみと言う事になります。特定のクラスを記述したく有りません。 その為、少なくとも私は提示頂いたエントリにある「var type = typeof(string);」の”string”様に型を直接指定する事が出来ません。 とりあえずなんらかの方法で型情報を設定出来る用になったと仮定して、typeof()内にフィールド参照用クラスを直接記述し下記をエントリ内のコードを書いてみましたがエラーとなってしまいます。エラーはCS1061でinstanctが”object”と認識している為instactにcreate()が定義が存在しないと判断してる様です。 var type = typeof(【ディレクトリから取得し認識出来たフィールド参照用クラス】); var genericType = typeof(Creater<>).MakeGenericType(type); var instanct = Activator.CreateInstance(genericType); instanct.create(type); typeof()に型を直接入れる以外に使用する方法、でも今回の問題を解決できそうな気がします。
退会済みユーザー

退会済みユーザー

2021/06/16 14:13 編集

> その為、少なくとも私は提示頂いたエントリにある「var type = typeof(string);」の”string”様に型を直接指定する事が出来ません。 Type.GetTypeでTypeオブジェクト取得したらどうでしょう
masahase

2021/06/16 14:42

返信ありがとうございます。 自作クラスの為かType.GetTypeで取得が出来ませんでしたが、下記エントリのGetTypeByClassNameを用いる事による文字列でTypeの取得が出来ました。 http://bochituku.jugem.jp/?eid=4 下記コードの実行でCreaterクラスのオブジェクトの取得は出来ました。  objの中身を見てみるとCreaterと表示されています。 しかし、objの型が"object"の為か内部のメソッドにcreate()にアクセス出来ません。 なにか良い方法はありますでしょうか? string className = "フィールド参照用クラス名" Type type = GetTypeByClassName(className); var genericType = typeof(Creater<>).MakeGenericType(type); object obj = Activator.CreateInstance(genericType);
退会済みユーザー

退会済みユーザー

2021/06/17 03:13 編集

> しかし、objの型が"object"の為か内部のメソッドにcreate()にアクセス出来ません。なにか良い方法はありますでしょうか? ジェネリック型の使用対象クラスが自作クラスとして、事前に引数が判っているのであれば、使用対象クラスにインターフェースを実装してそれにキャストしたり、判らないならdynamic型にするか、Type.InvokeMemberを使うことになります。
masahase

2021/06/17 10:47

使用するクラスは全て自クラスです。使用対象クラスにインターフェースを実装してそれにキャストがよくわからなかったですが、もう一度調べて見ようと思います。 object objをdynamic型にすると型情報が渡せた状態でcreateメソッドが実行出来ました! ただ実行出来たのは良いものの、createメソッド内では2つ以上のフィールド参照用クラス型を扱います。そのため、Starterクラスから送られた1つの型情報だけでは足りず、Createrクラスを複数のクラスに細分化して処理に対して必要な型は1つと言う少しややこしい構成になっています。 ひとまず、行いたい処理は出来た様に思いますので質問はここで閉じさせていだきます。ありがとうございました。
退会済みユーザー

退会済みユーザー

2021/06/17 16:00 編集

閉じられたので削除
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問