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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

解決済

3回答

42576閲覧

【C#】連番付きの変数をループで処理したい。

sujico.net

総合スコア453

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

2クリップ

投稿2017/01/27 01:08

編集2017/01/27 01:37

###前提・実現したいこと
C#プログラミングにおいて、
連番付きの変数があるとします。(string a1, string a2…など)
そもそもこんな変数の宣言をせずに、配列とか使えという話ですが、
どうしてもこういった実装を行わなければならない事態が発生しているので、そこは保留してください。

この連番の変数を、ループで回して1つずつ値を取得したいと考えています。
この連番はa1 ~ a99まであります。

string a1 = "AAA"; string a2 = "BBB"; ・ ・ ・ string a99 = "ZZZ";

そういったことは出来るでしょうか?
また、出来るとしたらどのような方法・コードの書き方をすればよいでしょうか。
C#初心者です。
宜しくお願い致します。

【追記】

(修正依頼内容1)
失礼いたしました。
クラス/構造体のメンバです。

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

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

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

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

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

haru666

2017/01/27 01:26 編集

変数ってローカル変数ですか?それともクラス/構造体のメンバですか?
guest

回答3

0

ベストアンサー

リフレクションで実装する方法と、愚直に書いておく方法の2パターンがあると思います。

C#

1// リフレクション 2// 今回はリフレクションにFastMemberを使います。 3// リフレクションは遅いため、何等かの方法でキャッシュしておくことが望ましいです 4// とりあえず既成の外部クラスを使います。nuget からFastMemberを探して使ってみてください。 5// FastMemberはクラスのアクセサ/ゲッタを生成してキャッシュしてくれるライブラリです。 6IEnumerable<string> AsEnumerable() 7{ 8 var accessor = TypeAccessor.Create(typeof(/*型*/)); 9 for (int i = 1; i < 99; ++i) 10 { 11 // 左側にリフレクションによって読み取りたいオブジェクト 12 // 右側にメンバーの名前を入れます 13 // クラスにメソッドを実装する場合を想定して今回は左側にthis、右側はメンバ名です。 14 yield return (string)accessor[this, $"a{i}"]; 15 } 16} 17 18// 拡張メソッド版 19public static IEnumerable<string> AsEnumerable(this /*型*/ obj) 20{ 21 var accessor = TypeAccessor.Create(obj.GetType()); 22 for (int i = 1; i < 99; ++i) 23 { 24 yield return (string)accessor[obj, $"a{i}"]; 25 } 26}

リフレクションにした方が遅いので、ここだけ特別っていうなら愚直に書いておいた方がいいです。
以下のようになるのでコード自体は長いですが、難しいこともありませんし…

C#

1// 愚直な方法1(こちらは拡張メソッドとしても実装しやすく元クラスを弄らなくとも良い) 2IEnumerable<string> AsEnumerable() 3{ 4 yield return a1; 5 yield return a2; 6 yield return a3; 7 yield return ... 8 yield return a99; 9} 10 11// 愚直な方法2(自然な形式で読み書きできる。) 12public string this[int index] 13{ 14 get 15 { 16 switch (index) 17 { 18 case 0: return a1; 19 case 1: return a2; 20 case 2: return a3; 21 // .... 22 case 98: return a99; 23 default: 24 throw new IndexOutOfRangeException(); 25 } 26 } 27 set 28 { 29 switch (index) 30 { 31 case 0: a1 = value; break; 32 case 1: a2 = value; break; 33 case 2: a3 = value; break; 34 // .... 35 case 98: a99 = value; break; 36 default: 37 throw new IndexOutOfRangeException(); 38 } 39 } 40}

追記
オマケ。コピペで使える全文です。

リフレクション

C#

1using FastMember; 2using System; 3using System.Collections.Generic; 4 5class Program 6{ 7 static void Main(string[] args) 8 { 9 var sample = new ReflectionSample(); 10 foreach (var str in sample.AsEnumerable()) 11 { 12 Console.WriteLine(str); 13 } 14 15 Console.ReadKey(); 16 } 17} 18 19public class ReflectionSample 20{ 21 public string a1 = "AAA"; 22 public string a2 = "BBB"; 23 public string a3 = "CCC"; 24} 25 26public static class ReflectionSampleExtension 27{ 28 public static IEnumerable<string> AsEnumerable(this ReflectionSample obj) 29 { 30 var accessor = TypeAccessor.Create(typeof(ReflectionSample)); 31 for (int i = 1; i < 3; ++i) 32 { 33 yield return (string)accessor[obj, $"a{i}"]; 34 } 35 } 36}

直書き

C#

1using System; 2using System.Collections.Generic; 3 4class Program 5{ 6 static void Main(string[] args) 7 { 8 var sample = new Sample(); 9 foreach (var str in sample.AsEnumerable愚直1()) 10 { 11 Console.WriteLine(str); 12 } 13 foreach (var str in sample.AsEnumerable愚直2()) 14 { 15 Console.WriteLine(str); 16 } 17 18 Console.ReadKey(); 19 } 20} 21 22public class Sample 23{ 24 public string a1 = "AAA"; 25 public string a2 = "BBB"; 26 public string a3 = "CCC"; 27 28 // 愚直1 29 public IEnumerable<string> AsEnumerable愚直1() 30 { 31 yield return a1; 32 yield return a2; 33 yield return a3; 34 } 35 36 public string this[int index] 37 { 38 get 39 { 40 switch (index) 41 { 42 case 0: return a1; 43 case 1: return a2; 44 case 2: return a3; 45 // .... 46 // case 98: return a99; 47 default: 48 throw new IndexOutOfRangeException(); 49 } 50 } 51 set 52 { 53 switch (index) 54 { 55 case 0: a1 = value; break; 56 case 1: a2 = value; break; 57 case 2: a3 = value; break; 58 // .... 59 // case 98: a99 = value; break; 60 default: 61 throw new IndexOutOfRangeException(); 62 } 63 } 64 } 65 66 public IEnumerable<string> AsEnumerable愚直2() 67 { 68 for (int i = 0; i < 3; ++i) 69 { 70 yield return this[i]; 71 } 72 } 73}

投稿2017/01/27 02:07

編集2017/01/27 02:58
haru666

総合スコア1593

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

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

sujico.net

2017/01/27 03:58

助かりました…ありがとうございます!
guest

0

VS2015以降ならnameofで変数名を文字列として取得できるので取得した文字列をキーにしたDictionaryを用意するという手が使えるかも

C#

1 var dic = new Dictionary<string, hogehoge>(); 2 dic.Add(nameof(a1), a1); 3 ~中略~ 4 dic.Add(nameof(a99), a99); 5 6 int i= 0; 7 // ループで初期値を代入(次の行をループの中に書く) 8 dic[$"a{i}"] = new hogehoge(){ho = "ho", ge = "ge"}; 9 10 // 以下は実際に取り出すぱてぃーん 11 textbox1.Text = dic[$"a{i}"].ho.ToString();

眠くてかなり端折ってるから使いたいように改変でおk
作ったdic自体をローカル変数でなくどこかのプロパティやプライベート変数で確保しておけばクラスのコンストラクタでDictionaryに格納すればいいと思う
でも、本人も書いてる通りこんな作りになってる時点で再設計したほうがいいと思う

投稿2017/01/27 15:49

len_souko

総合スコア1363

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

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

0

int iでループさせつつ
指定した変数名の変数を取得を使いアクセスすればいけると思います。

C#

1for(int i = 1;i<100;i++){ 2 var ikey = "a" + i.toString(); 3 4 ・・・ 5}

投稿2017/01/27 01:56

NarugaL_ove

総合スコア108

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

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

sujico.net

2017/01/27 03:59

その方法もありましたか…思い浮かびませんでした。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問