###前提・実現したいこと
C#プログラミングにおいて、
連番付きの変数があるとします。(string a1, string a2…など)
そもそもこんな変数の宣言をせずに、配列とか使えという話ですが、
どうしてもこういった実装を行わなければならない事態が発生しているので、そこは保留してください。
この連番の変数を、ループで回して1つずつ値を取得したいと考えています。
この連番はa1 ~ a99まであります。
string a1 = "AAA"; string a2 = "BBB"; ・ ・ ・ string a99 = "ZZZ";
そういったことは出来るでしょうか?
また、出来るとしたらどのような方法・コードの書き方をすればよいでしょうか。
C#初心者です。
宜しくお願い致します。
【追記】
(修正依頼内容1)
失礼いたしました。
クラス/構造体のメンバです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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総合スコア1593
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
総合スコア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
総合スコア108
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。