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

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

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

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

Q&A

解決済

2回答

6731閲覧

C#のジェネリックで受け取った配列をforeachで回したい

退会済みユーザー

退会済みユーザー

総合スコア0

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

0グッド

2クリップ

投稿2019/03/30 12:28

前提・実現したいこと

C#でジェネリックを使ったクラスで、stringやint等の 配列 を受け取って、
foreachで処理する方法を知りたいです。

該当のソースコード

C#

1private string ListSum<Type>(Type obj) 2{ 3 string str = ""; 4 foreach(Type st in obj){ 5 str += $"{st,-10}"; 6 } 7 return str; 8} 9

発生している問題・エラーメッセージ

error CS1579: foreach ステートメントは、'Type' が 'GetEnumerator' のパブリック定義を含んでいないため、型 'Type' の変数に対して使用できません。

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

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

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

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

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

guest

回答2

0

ベストアンサー

回答させていただきます。
引数は配列にすべきではないですか?

[追記] Zuishinさんのアドバイスを元に回答を修正します。

List<T>配列はどちらもIEnumerable<T>を実装しているので、オーバーロードするのではなく下記のように変更しました。Zuishinさんが詳しく説明されておりますので是非コメントもお読みください。

Zuishinさんありがとうございます。
大変勉強になりました。

C#

1string ListSum<Type>(IEnumerable<Type> obj) 2{ 3 string str = ""; 4 foreach (Type st in obj) 5 { 6 str += $"{st,-10}"; 7 } 8 return str; 9}

IEnumerable<T> Interface
指定した型のコレクションに対する単純な反復処理をサポートする列挙子を公開します。

参照元 https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic.ienumerable-1?view=netframework-4.7.2

旧回答

C#

1string ListSum<Type>(Type[] obj) 2{ 3 string str = ""; 4 foreach (Type st in obj) 5 { 6 str += $"{st,-10}"; 7 } 8 return str; 9} 10 11string ListSum<Type>(List<Type> obj) 12{ 13 string str = ""; 14 foreach (Type st in obj) 15 { 16 str += $"{st,-10}"; 17 } 18 return str; 19}

投稿2019/03/30 12:56

編集2019/03/30 19:11
IShix

総合スコア1724

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

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

Zuishin

2019/03/30 13:34

それで解決しますがこの場合は IEnumerable<T> がいいと思います。そうすればコードを二種類書かなくて済みますし、汎用性が高くなります。 IEnumerable<T> → IReadOnlyList<T> → IList<T> と派生し、配列も List<T> もともに IList<T> を実装するので、ランダムアクセスが必要な場合は IReadOnlyList<T> または IList<T> を使うのが常套手段です。
退会済みユーザー

退会済みユーザー

2019/03/31 07:01

[]をつければよかったんですね。 Zuishinさんも、詳しく教えてくれてありがとうございます。 それを読んで更に丁寧に教えてくれたIShikawanさんありがとうございます。
IShix

2019/03/31 07:48 編集

僕も大変勉強になりました。ありがとうございます。 せっかく汎用性のある関数になったので、数値型のみ(int, long, double, float)の制約を導入したいと思いませんか?制限したいのですが、数値型はシールされたクラスなので有効な制約ではないようです。一般的なのか分かりませんがinterfaceで個別に指定し制限する方法が紹介されているのを見つかりました。 お手数ですがご存知でしたらご教授いただきたいです。 Zuishinさんのご意見もお伺いしたいです。
Zuishin

2019/03/31 07:52 編集

数値には IArithmetic インターフェースを実装する予定があったみたいですが、パフォーマンス上の理由で省かれています。普通の方法で簡単に数値に制限するのはできないんじゃないかと思います。 https://qiita.com/Zuishin/items/61fc8807d027d5cea329 の chocolamint さんのコメントはヒントになりますか?
IShix

2019/03/31 09:53 編集

> Zuishinさん さっそくのご回答ありがとうございます。IArithmeticは初めて知りました。 そういう経緯もあったんですね。勉強になります。 リンク先拝見させていただきました。 無理やり計算するというアイディアがすごいですね! 実行してみないと分からないのは少し気になりました。 僕なりにも調べてみたのですが、数値型はstruct且つIConvertibleを実装しているので、この2つを制約にするのは安直過ぎますか? string ListSum<Type>(IEnumerable<Type> obj) where Type : struct, IConvertible ヒントになった記事 https://stackoverflow.com/questions/11770882/c-sharp-generic-method-with-integer-constraint-refuses-to-cast-from-integer-to-t#answer-11770902 IConvertible https://docs.microsoft.com/ja-jp/dotnet/api/system.iconvertible?view=netframework-4.7.2
Zuishin

2019/03/31 08:38 編集

IConvertible を実装した構造体は自分で作れますから数値を対象にしたというには微妙ですね。long と double のどちらにコンバートするのかという問題が出てきます。しかし目的によっては面白いと思います。
IShix

2019/03/31 09:21 編集

ご意見大変参考になります。やっぱり安直過ぎましたね。 IConvertible を実装した構造体を作ろうと思った事ないのでギリいけるかと思ったのですが、Zuishinさんのような詳しい方には逆に混乱させてしまいそうですね。 色々考えたのですが、下記方法を取ろうと思います。 ・構造体を制約 ・関数先頭にAssertで型チェック ・関数名にはなるべく数値演算っぽい名前をつける ・<summary>で補足 正直どういうエラーや落とし穴が存在するか分かりませんが、内容を熟知して未知のエラーに備えるより、なるべく制限を掛ける実装が好きなのでこのようにしたいと思います。 Zuishinさん おかげさまで大変勉強になりました。 ありがとうございます。
guest

0

別の方法として、Enumereble.Aggregate() を利用する方法もあります。

C#

1string ListSum<T>( IEnumerable<T> list ) 2{ 3 return list.Aggregate( "", ( x, y ) => x + $"{y, -10}" ); 4}

投稿2019/03/31 03:45

draq

総合スコア2573

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問