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

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

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

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

Q&A

解決済

4回答

13333閲覧

ジェネリクスで変数を指定したい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

1クリップ

投稿2018/05/01 00:57

編集2018/05/01 01:16

質問

ジェネリクスで変数を指定した場合以下のエラーが出ました。
ジェネリクスで変数を指定することは不可能なのでしょうか?

エラー CS0118 'type' は 変数 ですが、種類 のように使用されています。

エラーが出ないプログラム

c#

1class Program 2{ 3 class MyClass1 { } 4 class MyClass2 { } 5 6 static void Deserialize<T>(byte[] data) 7 { 8 // デシリアライズ処理 9 Console.WriteLine("Deserialize<T> is called"); 10 } 11 12 static void Main(string[] args) 13 { 14 var data = new byte[] { 1, 2, 3 }; 15 16 // data の1バイト目で、 17 // どのクラスとしてデシリアライズするかを別ける 18 switch(data[0]) 19 { 20 case 1: 21 // data の1バイト目を飛ばす 22 data = data.Skip(1).ToArray(); 23 Deserialize<MyClass1>(data); 24 break; 25 case 2: 26 // data の1バイト目を飛ばす 27 data = data.Skip(1).ToArray(); 28 Deserialize<MyClass2>(data); 29 break; 30 } 31 } 32}

エラーが出るプログラム

c#

1class Program 2{ 3 class MyClass1 { } 4 class MyClass2 { } 5 6 static void Deserialize<T>(byte[] data) 7 { 8 // デシリアライズ処理 9 Console.WriteLine("Deserialize<T> is called"); 10 } 11 12 static void Main(string[] args) 13 { 14 var data = new byte[] { 1, 2, 3 }; 15 16 var types = new Dictionary<int, Type> 17 { 18 [1] = typeof(MyClass1), 19 [2] = typeof(MyClass2) 20 }; 21 22 // data の1バイト目で、 23 // どのクラスとしてデシリアライズするかを別ける 24 var type = types[data[0]]; 25 // data の1バイト目を飛ばす 26 data = data.Skip(1).ToArray(); 27 Deserialize<type>(data); // ここでエラーになる 28 } 29}

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

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

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

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

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

guest

回答4

0

こんにちは。

Deserialize<T>のシグニチャはどの型の場合でも同じなので、DictionaryにtypeではなくDeserialize<T>のデリゲートを登録して、それを呼び出せば近しいことができるだろうと思います。

投稿2018/05/01 01:49

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2018/05/01 02:54

ありがとうございます、なるほどですね! 試しに書いてみた所delegateで動きました。 プログラム https://ideone.com/wAcqMS 出力 Deserialize<Test.Program+MyClass1> is called
guest

0

ベストアンサー

できません。
求める結果を出す方法はいくつかありますが、Deserialize() を書き換えないなら次のようにします。

C#

1using System; 2using System.Reflection; 3 4namespace ConsoleApp1 5{ 6 class Program 7 { 8 class MyClass1 { } 9 10 static void Deserialize<T>(byte[] data) 11 { 12 foreach (var datum in data) 13 { 14 Console.WriteLine(datum); 15 } 16 } 17 18 static void Main(string[] args) 19 { 20 var data = new byte[] { 1, 2, 3}; 21 var type = typeof(MyClass1); 22 23 // (1) 問題ない 24 //Deserialize<MyClass1>(data); 25 26 // (2) エラー 27 typeof(Program) 28 .GetMethod(nameof(Deserialize), BindingFlags.Static | BindingFlags.NonPublic) 29 .MakeGenericMethod(new[] { type }) 30 .Invoke(null, new[] { data }); 31 Console.ReadKey(); 32 } 33 } 34}

投稿2018/05/01 01:08

Zuishin

総合スコア28660

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

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

退会済みユーザー

退会済みユーザー

2018/05/01 01:38

ありがとうございます。 リフレクションを使うしかないのですね。
Zuishin

2018/05/01 01:41

質問に書かれた情報からのみ判断するとそれが最適と思います。 MyClass の型を変数 type に入れなければならないかどうかというところも検討してみてください。
guest

0

そりゃそこは変数を指定するところじゃないからです。

投稿2018/05/01 01:04

y_waiwai

総合スコア87774

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

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

0

ジェネリクスに渡す型名は静的に決定されたものでなければいけないのでこれはできないです。

質問者さんがやりたいのはこういうことなのでは?

Type からインスタンスを生成する

投稿2018/05/01 01:20

SAM-tak

総合スコア199

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問