• ベストアンサー

C#で変数名の取得

C#2.0を使っています。 例えば string s = "test"; という変数名「s」があったときに、この変数名を Reflectionか何かを利用して取得することはできないでしょうか? s.GetType().NameなどでString(型)は取得できるのですが 変数名「s」を取得したいのです。

質問者が選んだベストアンサー

  • ベストアンサー
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

変数といえば、「フィールド」「引数」「ローカル変数」がありますがどれでしょうか? 私の調べた範囲では、 「フィールド」は可能 「引数」は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); } } } }

takagoo100
質問者

お礼

ご返答ありがとうございます。 取得したいのは引数だと思います。 すいません、お題から逸れるかもしれませんが、 そもそもなんで変数名を取得したいと思ったかというと、 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); 型を気にせず引数に渡して展開された変数を表示します。 申し訳ないのですが、このようなことをふまえて アドバイス頂けないでしょうか? 代わりになるやり方(関数)など知っていましたら教えてもらいたいです。

takagoo100
質問者

補足

 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();   }  }

その他の回答 (1)

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2
takagoo100
質問者

お礼

ご返答ありがとうございます。 なるほど、同じような質問があったんですね・・・ 試してみましたが、たしかに多次元配列はエラーがでましたが ジャグ配列は大丈夫でした。 あとはこのやり方を利用して自分なりにカスタマイズ(インデントの幅を調節できたりしたら理想ですね) していきたいと思います。参考になりました。

関連するQ&A