- ベストアンサー
C#で変数名の取得
C#2.0を使っています。 例えば string s = "test"; という変数名「s」があったときに、この変数名を Reflectionか何かを利用して取得することはできないでしょうか? s.GetType().NameなどでString(型)は取得できるのですが 変数名「s」を取得したいのです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
変数といえば、「フィールド」「引数」「ローカル変数」がありますがどれでしょうか? 私の調べた範囲では、 「フィールド」は可能 「引数」はNameからインスタンスが取れないので無理 「ローカル変数」はNameも取れないので無理(コンパイルした時点で名前を保持していない?) namespace ConsoleApplication1 { class Program { static void Main(string[] args) { (new myClass()).foo("引数"); } } class myClass { string s1 = "フィールド"; public void foo(string s2) { string s3 = "ローカル変数"; //フィールドの情報 FieldInfo[] fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo field in fields) { object v = field.GetValue(this); Console.WriteLine("[field]" + field.Name + "=" + v +"," + (v == (object)s1)); } //引数の情報 ParameterInfo[] parameters = MethodBase.GetCurrentMethod().GetParameters(); foreach (ParameterInfo parameter in parameters) { Console.WriteLine("[parameter]" + parameter.Name); } //ローカル変数の情報 IList<LocalVariableInfo> localVariables = MethodBase.GetCurrentMethod().GetMethodBody().LocalVariables; foreach (LocalVariableInfo localVariable in localVariables) { Console.WriteLine("[localVariable]" + localVariable.LocalType); } } } }
その他の回答 (1)
- todo36
- ベストアンサー率58% (728/1234)
お礼
ご返答ありがとうございます。 なるほど、同じような質問があったんですね・・・ 試してみましたが、たしかに多次元配列はエラーがでましたが ジャグ配列は大丈夫でした。 あとはこのやり方を利用して自分なりにカスタマイズ(インデントの幅を調節できたりしたら理想ですね) していきたいと思います。参考になりました。
お礼
ご返答ありがとうございます。 取得したいのは引数だと思います。 すいません、お題から逸れるかもしれませんが、 そもそもなんで変数名を取得したいと思ったかというと、 PHPでいうvar_dump関数のような、 変数やクラスや配列などを引数に渡して表示してくれる関数を C#でも作りたいと思ったからです(var_dumpもローカル変数名などは表示されませんけど・・・) 一応探したりしたのですが似たような機能はなかったので、 VisualStadioのデバッグの変数表示機能も使ってみたのですが、 見易さと使い勝手から、やっぱりvar_dumpのような一発で全体像が見えるような 機能がほしいと思いました。 そこで自分なりに考えてみたのですが、 ※クラスの定義は補足を参考にしてください string s1 = "test"; Debugger.Dump(s1); List<int> list = new List<int>(); list.Add(11); list.Add(22); Debugger.Dump(list); TestClass tc = new TestClass(); tc.a = 1; tc.testClass = new TestClass(); tc.testClass.a = 2; Debugger.Dump(tc); 型を気にせず引数に渡して展開された変数を表示します。 申し訳ないのですが、このようなことをふまえて アドバイス頂けないでしょうか? 代わりになるやり方(関数)など知っていましたら教えてもらいたいです。
補足
public class Debugger { static protected List<Abstract> writers = new List<Abstract>(); static private string indent = "\t"; static public string Indent { get { return indent; } set { indent = value; } } static public void Dump(object src) { #region "デフォルトでライターの追加" StringBuilder output = new StringBuilder(); output.Append(RecursiveGetBuffer(src, 0, -1)); foreach (Abstract writer in writers) { // System.Windows.Forms.MessageBox.Show(output.ToString()); // System.Console.WriteLine(output.ToString()); // など writer.Write(output.ToString()); } } static public void AddWiter(Abstract writer) { writers.Add(writer); } static private string GetMultiIndent(int count) { string s = ""; for (int i = 0; i < count; i++) { s += Indent; } return s; } static private string GetFormatType(object obj) { return "[" + obj.GetType().ToString() + "] => "; } static private string RecursiveGetBuffer(object src, int recursive, int index) { StringBuilder output = new StringBuilder(); if (src == null) { // 本当は型情報などを取得して表示したいけど、nullなのでやむおえず output.Append(GetMultiIndent(recursive) + " null" + Environment.NewLine); } else { Type type = src.GetType(); if (type.IsPrimitive || type == typeof(string) || type.IsEnum) { if (index < 0) { output.Append(GetMultiIndent(recursive) + GetFormatType(src) + src + Environment.NewLine); } else { // 配列の中身を表示する場合 output.Append(GetMultiIndent(recursive) + "[" + index + "]" + " => " + src + Environment.NewLine); } } else { output.Append(GetMultiIndent(recursive) + GetFormatType(src) + Environment.NewLine + GetMultiIndent(recursive) + "(" + Environment.NewLine); if (type.IsArray) { int n = 0; foreach (object temp in (Array)src) { recursive++; output.Append(RecursiveGetBuffer(temp, recursive, n)); recursive--; n++; } } else if (type.IsGenericType) { int n = 0; #region "C#2.0では動的型がないためそれぞれの型を用意する。C#4.0で可能?" List<string> stringSrc = src as List<string>; List<int> intSrc = src as List<int>; if (stringSrc != null) { foreach (object temp in stringSrc) { recursive++; output.Append(RecursiveGetBuffer(temp, recursive, n)); recursive--; n++; } } else if (intSrc != null) { foreach (object temp in intSrc) { recursive++; output.Append(RecursiveGetBuffer(temp, recursive, n)); recursive--; n++; } } #endregion } else if (type.IsClass) { recursive++; foreach (FieldInfo fi in type.GetFields()) { object value = fi.GetValue(src); output.Append(RecursiveGetBuffer(value, recursive, -1)); } recursive--; } output.Append(GetMultiIndent(recursive) + ")" + Environment.NewLine); } } return output.ToString(); } }