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

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

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

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

Unity

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

Q&A

解決済

4回答

12994閲覧

【C#】ジェネリッククラスをListに指定する方法はありませんか?

nkkn1446

総合スコア10

C#

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

Unity

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

0グッド

0クリップ

投稿2015/07/01 14:00

編集2015/07/02 14:59

現在Unityでゲームを作りつつC#を勉強しているのですが、ジェネリッククラスの基底クラスとしての扱いかたに困っています。

lang

1// クラス定義 2public class Base<T> : MonoBehaviour where T : Base<T> { 3 public static T CreateInstance() { 4 GameObject obj = new GameObject(); 5 T component = obj.AddComponent<T>(); // Tクラスの実体を生成する 6 return component; 7 } 8} 9 10public class A : Base<A> { 11 // Aクラスの定義 12} 13 14public class B : Base<B> { 15 // Bクラスの定義 16}

MonoBehaviourというUnityのクラスを継承するとnew()ができなくなるため、別途実体を生成するためのメソッドを定義する必要があります。

そのメソッドを派生クラスから呼び出した際に型を指定せずに済むようジェネリッククラスを使用しているのですが、下記のような指定をするとエラーになってしまいます。

lang

1// Base<T>を型指定してListに格納する 2List<Base<T>> bases = new List<Base<T>> { 3 A.CreateInstance(), 4 B.CreateInstance() 5}; 6// ジェネリックメソッドのwhereにBase<T>を指定する 7void func<Type>() where Type : Base<T> { 8}

特別ジェネリッククラスを使わなければいけないわけではないので、他に解決する方法がないかご教授いただけると幸いです。

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

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

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

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

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

guest

回答4

0

Unity でなくても普通に C# でそのようなことはできません。

別の手段はないか

そもそもどういうことがしたいのかによりますが、例えば、次のように Base<T> の上にインタフェースを設けたりする必要があります。

using System; using System.Collections.Generic; interface IBase { int hoge(); } public class Base<T> : IBase where T : new() { public T func() { return new T(); } public int hoge(){ return 1; } } public class A : Base<A> {} public class B : Base<B> {} class Program { static void Main(string[] args) { List<IBase> bases = new List<IBase> {new A(), new B()}; } }

投稿2015/07/01 14:32

ngyuki

総合スコア4514

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

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

nkkn1446

2015/07/02 05:08

ありがとうございます。interface試してみます。
guest

0

自己解決

ジェネリッククラスのまま実現するのは中々難しいようなので、ジェネリックメソッドで実現することにします。
迅速な回答をいただき、ありがとうございました。

投稿2015/07/04 06:02

nkkn1446

総合スコア10

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

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

0

MonoBehaviourにデフォルトコンストラクタがないのが原因ならデフォルトコンストラクタを持つ派生クラス作ってあげれば良いんじゃない?とか思いましたがどうでしょう?

lang

1// 勝手な想像 2class MonoBehaviour 3{ 4 protected MonoBehaviour(){} 5} 6 7// だったら・・・ 8class Base : MonoBehaviour 9{ 10 public Base() 11 : base() 12 { 13 // 省略 14 } 15} 16public class A : Base{} 17public class B : Base{} 18 19class Program 20{ 21 static void Main(string[] args) 22 { 23 List<Base> bases = new List<Base> {new A(), new B()}; 24 } 25}

投稿2015/07/03 05:53

Ryzna

総合スコア85

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

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

Ryzna

2015/07/03 06:07 編集

ごめんなさい。 これMonoBehaviourのコンストラクタinternalなんですよね・・・ 見当違いでした。
guest

0

lang

1List<dynamic> bases = new List<dynamic> { new A(), new B() };

dynamicを使えばできなくはないけどまあ扱いづらいです。

そもそも、もっと簡潔な設計ができないか考えたほうがいいのかもしれません。


追記
Unityではdynamic使えなかったですね。
すみません。

投稿2015/07/01 15:16

編集2015/07/02 00:32
sho_cs

総合スコア3541

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

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

nkkn1446

2015/07/02 05:07 編集

ご回答ありがとうございます。 設計についてはジェネリッククラスを使用せずに A a = Base.func<A>(); とすることでも実現できるのですが、もっと簡潔に書けないかなと思って質問した次第です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問