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

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

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

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

Q&A

解決済

1回答

2549閲覧

匿名クラスのEnumerable

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2019/01/17 16:58

編集2019/01/19 04:02

前提・実現したいこと

前回の質問で、下記コードについて教わったのですが、

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Linq; 5 6public class LinqTest : MonoBehaviour 7{ 8 void Start () 9 { 10 var list = new List<string>(); 11 list.Add ( "AAA" ); 12 list.Add ( "BBB" ); 13 list.Add ( "CCC" ); 14 15 // (1) で、元のリストの値 x と、int型 i を持つ匿名型(のIEnumerable)に変換 16 // (2) で、i を Key、x を Value とする Dictionary に変換 17 var dictionary = list.Select((x, i) => new { x, i} ) // (1) 18 .ToDictionary(d => d.i, d => d.x); // (2) 19 20 // 確認用 21 foreach ( var item in dictionary ) 22 { 23 Debug.Log ( $"{item.Key}, {item.Value}" ); 24 } 25 } 26}

これに関して、下記のことは教わり理解、確認しました。

・xが要素で、iが要素番号。 ・.ToDictionaryでDictionaryが生成できる過程。 ・new { } は匿名型のクラス。 ・実際にエディタでオンマウスでxやiの型を確認。 ・list.Select((x, i) => new {x, i})で匿名クラスのIEnumerableに変換される。

ただ、実際にこのIEnumerableを出力して中身を確かめる処理をしたくなり、
コードを組んだのですが、それができませんでした。
また、list.Select((x) => new {x}))としたときの中身も出力して比較を試みたかったのですが、
同様にできませんでした。
ご教示お願いします。

試したこと

C#

1 var list = new List<string>(); 2 list.Add ( "AAA" ); 3 list.Add ( "BBB" ); 4 list.Add ( "CCC" ); 5 6 var en = list.Select((x, i) => new {x, i}); 7 8 Debug.Log(en); 9 //System.Linq.Enumerable+<CreateSelectIterator>c__Iterator11`2[System.String,<>__AnonType0`2[System.String,System.Int32]] 10 11 foreach(string s in en) 12 { 13 Debug.Log(s); 14 }

foreachでエラーが起きます。
エラーメッセージ。

Cannot convert type `anonymous type' to `string'

同様に、

C#

1var en = list.Select((x) => new {x});

にしても、下記エラーメッセージが出力されます。

エラーメッセージ。

Cannot convert type `anonymous type' to `string'

追記

dynamicというものがあるらしくて、試してみましたが、下記エラーが出てしまいました。
匿名クラスのIEnumerable型を生成するには、<>に何を指定すればよいのでしょうか?
var enにすると、IEnumerable型ではなくなります。

IEnumerable<dynamic> en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; Debug.Log(en); foreach(var s in en){ Debug.Log(s.x +","+s.i); }
Dynamic keyword requires `System.Runtime.CompilerServices.DynamicAttribute' to be defined. Are you missing System.Core.dll assembly reference?

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

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

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

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

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

guest

回答1

0

ベストアンサー

enに入っているのが匿名型でありstringではないので
foreach(string s in en)はできません

型推測(var)を用いて

c#

1foreach(var s in en){ 2 Debug.Log($"[x={s.x}, i={s.i}]"); 3}

などとしてください。


C#

1IEnumerable<object> en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; 2// System.Collections.IEnumerable en = でも可能 3// var enが一番いいと思いますが 4 5Console.WriteLine(en); 6 7foreach(dynamic s in en) 8{ 9 Console.WriteLine(s.x); 10}

投稿2019/01/17 22:20

編集2019/01/19 04:41
asm

総合スコア15147

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

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

退会済みユーザー

退会済みユーザー

2019/01/18 02:05

ご回答ありがとうございます。 ご提示の方法でできました。 あと、すみません、もう1点質問し忘れていたのですが、 試したことのソースコードで、Debug.Log(en);をとると、 次の行のコメントのように長い出力がとれるのですが、 もう少し短い出力でEnumerable型だとわかるような出力をとる方法ってありますか? Debug.Log(en.GetType()); を試しましたが、コメント同じ出力となりました。
asm

2019/01/18 03:12

なんのために判別できる出力が必要なのでしょうか?
退会済みユーザー

退会済みユーザー

2019/01/18 08:01 編集

ご回答ありがとうございます。 すみません、匿名クラスのEnumerable型がまだよくわかってなくて、出力方法を変えてみたら何かわかるのではないかと思って質問させていただいのですが、よく考えて、自分で理解していない所がわかりました。 目的は、 Selectメソッドの戻り値で匿名クラスのEnumerable型を生成する方法でなく、 初期化で匿名クラスのEnumerable型を作る方法を知りたいです。 例えば、初期化で、int型のEnumerable型を生成する場合は下記でできますが、 IEnumerable<int> en = new int[] { 123, 456, 789 }; これが、new {a=1, b=1}, new {a=2, b=2}, new {a=3, b=3} のような匿名クラスを要素とする Enumerable型を生成したい場合、どのように書けばわからない為、知りたいです。 ご教示お願いします。
asm

2019/01/18 10:52

IEnumerable en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}};
退会済みユーザー

退会済みユーザー

2019/01/18 14:09

ご回答ありがとうございます。 IEnumerable en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; こちら試したのですが、 Using the generic type `System.Collections.Generic.IEnumerable<T>' requires `1' type argument(s) というエラーが出てしまいました。 ちなみに var en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; Debug.Log(en); で試したところ、 <>__AnonType0`2[System.String,System.Int32][] と出力され、Enumerable型ではなくなりました。
asm

2019/01/19 04:36 編集

配列はIEnumerable<T>を実装しているクラスなので IEnumerable<T>として扱っていいと思いますが なんの問題があるんでしょうか?
退会済みユーザー

退会済みユーザー

2019/01/19 12:16

ご回答ありがとうございます。 Tに何の型を指定すれば、エラーが出ずに、 IEnumerable<?> en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; のコードが通るかを知りたかったです。 >配列はIEnumerable<T>を実装しているクラスなので >IEnumerable<T>として扱っていい こちらは、 var en = new[]{ new{x = "AAA", i = 0}, new {x ="BBB", i = 1}, new {x = "CCC", i = 2}}; のenをIEnumerable<T>とみなしてよいという意味でしょうか?
asm

2019/01/19 13:11

> のenをIEnumerable<T>とみなしてよいという意味でしょうか? ええそうです。
退会済みユーザー

退会済みユーザー

2019/01/19 13:13

ご回答ありがとうございました。 勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問