お世話になります。現在変数でプロパティを取得する方法がないか調べているのですが、上手くいっておりません。
アドバイスを頂けましたら有難いです。
C#
1 public static class Message 2 { 3 public static readonly string Message1 = "ok"; 4 public static readonly string Message2 = "ng"; 5}
C#
1他クラス 2var Choice = "1" 3MessageBox.Show(Message + Choice);//このように変数で指定したmessageを取得したいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/30 09:44
2021/11/30 10:14
退会済みユーザー
2021/11/30 23:49
回答3件
0
質問のコメントにも書きましたが、質問の Message クラス定義の中にあるのはプロパティではなくてフィールドと言います。
MessageBox.Show(Message + Choice);//このように変数で指定したmessageを取得したいです。
そういうことはできないので別の手段を考えましょう。String の配列にして添え字で取得するとか。
例えば以下のように Message1 と Message2 の配列を返すパブリックプロパティを定義して、
// 静的クラスで String 型の配列を返すパブリック // プロパティ定義して利用 public static class Message { // フィールドを public にするのはお勧めしません private static readonly string Message1 = "ok"; private static readonly string Message2 = "ng"; // パブリックプロパティを定義 public static string[] Messages { get { return new String[] { Message1, Message2 }; } } }
それを以下のように利用してはいかがですか?
MessageBox.Show(Message.Messages[0]); MessageBox.Show(Message.Messages[1]);
以下はお勧めはしませんが・・・
Message.Messages[0] のような形にするのが気に入らないとか、どうしても Massage + index という形にしたいなら、Message クラスをインスタンスクラスとして定義してインデクサを使うとか、演算子 + をオーバーロードするとかいう方法もあります。以下のような感じ。
using System; namespace ConsoleAppOverload { internal class Program { static void Main(string[] args) { // インスタンスクラスにしてインデクサを定義 // または演算子 + をオーバーロード var message = new Message(); // インデクサ Console.WriteLine("-----インデクサ-----"); for (int index = 1; index < 4; index++) { Console.WriteLine(message[index]); } // 演算子 + オーバーロード Console.WriteLine("-----演算子オーバーロード-----"); for (int index = 1; index < 4; index++) { Console.WriteLine(message + index); } } } // インスタンスクラスにしてインデクサを定義 // または演算子 + をオーバーロード public class Message { // フィールドを public にするのはお勧めしません private static readonly string Message1 = "ok"; private static readonly string Message2 = "ng"; // インデクサを定義 public string this[int index] { get { if (index == 1) return Message1; else if (index == 2) return Message2; else return "未定義"; } } // 演算子 + をオーバーロード public static string operator +(Message msg, int index) { if (index == 1) return Message1; else if (index == 2) return Message2; else return "未定義"; } } }
結果は:
投稿2021/12/01 01:30
編集2021/12/01 01:48退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
とりあえず、プロパティとフィールドを間違えてると思います。
リフレクション使えば出来ると言えば出来ますけど、普通にアクセスするより面倒だし速度も非常に遅くなります。
C#
1using System; 2using System.Reflection; 3 4public static class Message 5{ 6 public static readonly string Message1 = "ok"; // これはフィールド 7 public static string Message2 { get; } = "ng"; // これがプロパティ 8} 9 10class Program 11{ 12 static void Main() 13 { 14 var choice = "1"; 15 var fieldMessage1 = typeof(Message).GetField( 16 "Message" + choice, 17 BindingFlags.Static | BindingFlags.Public); 18 19 Console.WriteLine(fieldMessage1.GetValue(null)); // okが出力される 20 21 choice = "2"; 22 var propMessage2 = typeof(Message).GetProperty( 23 "Message" + choice, 24 BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public); 25 26 Console.WriteLine(propMessage2.GetValue(null)); // ngが出力される 27 28 Console.ReadKey(); 29 } 30}
文字列で値を持ってくるならDictionaryがありますし、別に文字列である必要が無いなら、配列やListもあります。
cs
1using System; 2using System.Collections.Generic; 3 4class Program 5{ 6 private static readonly string[] _ArrayMessage = 7 { 8 "ok", 9 "ng", 10 }; 11 12 private static readonly Dictionary<string, string> _DictMessage = new Dictionary<string, string>() 13 { 14 {"Message1", "ok"}, 15 {"Message2", "ng"}, 16 }; 17 18 static void Main() 19 { 20 Console.WriteLine(_ArrayMessage[0]); 21 Console.WriteLine(_DictMessage["Message1"]); 22 23 Console.ReadKey(); 24 } 25}
リフレクションの速度が非常に遅いと言われても、どれくらい遅いのかピンと来ないと思うので、BenchmarkDotNet の計測結果を載せておきます。
cs
1using BenchmarkDotNet.Attributes; 2using BenchmarkDotNet.Diagnosers; 3using BenchmarkDotNet.Running; 4using System.Collections.Generic; 5using System.Reflection; 6 7public static class Message 8{ 9 public static string Message1 { get; } = "ok"; 10 public static string Message2 { get; } = "ng"; 11} 12 13//計測用テストクラス 14[MemoryDiagnoser(false)] 15[ShortRunJob] 16public class Test 17{ 18 private static readonly string[] _ArrayMessage = 19 { 20 "ok", 21 "ng", 22 }; 23 24 private static readonly Dictionary<string, string> _DictMessage = new Dictionary<string, string>() 25 { 26 {"Message1", "ok"}, 27 {"Message2", "ng"}, 28 }; 29 30 private int _Index = 0; 31 private string _StringKey = "1"; 32 33 [Benchmark] 34 public string UseReflection() 35 { 36 var prop = typeof(Message).GetProperty( 37 "Message" + _StringKey, 38 BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public); 39 40 return (string)prop.GetValue(null); 41 } 42 43 [Benchmark] 44 public string UseArray() => _ArrayMessage[_Index]; 45 46 [Benchmark] 47 public string UseDictionary() => _DictMessage["Message" + _StringKey]; 48} 49 50class Program 51{ 52 static void Main() 53 { 54 BenchmarkRunner.Run<Test>(); 55 } 56} 57 58(計測結果) 59| Method | Mean | Error | StdDev | Median | Allocated | 60|-------------- |------------:|-----------:|----------:|------------:|----------:| 61| UseReflection | 202.8417 ns | 13.9314 ns | 0.7636 ns | 203.0229 ns | 48 B | 62| UseArray | 0.0055 ns | 0.1723 ns | 0.0094 ns | 0.0000 ns | - | 63| UseDictionary | 47.3129 ns | 9.5924 ns | 0.5258 ns | 47.3259 ns | 48 B |
投稿2021/11/30 08:46
編集2021/12/01 01:52退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/11/30 08:58
0
リフレクションを使ってみては?
C#
1using System; 2using System.Reflection; 3 4public static class Message 5{ 6 public static readonly string Message1 = "ok"; 7 public static readonly string Message2 = "ng"; 8 9 public static string GetValue(string index) { 10 FieldInfo fieldInfo = typeof(Message).GetField(index, 11 BindingFlags.Public | BindingFlags.Static); 12 if (fieldInfo == null) { 13 throw new ArgumentOutOfRangeException(); 14 } 15 return (string)fieldInfo.GetValue(null); 16 } 17}
C#
1var msg1 = Message.GetValue("Message1"); // ok 2var msg2 = Message.GetValue("Message2"); // ng
"1" とか "2" を引数にするなら GetField の第1引数を "Message" + index とかにしてください。
投稿2021/11/30 08:45
総合スコア2707
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。