title: How do I get the name of a parameter passed to my function?
body: <p>(<em>Sorry if this is a duplicate, but I've been doing a lot of searching and haven't found an answer</em>)</p>
  
  <p>I'm currently working on a object save/load system that allows me to save data between sessions, namely settings and the like. My current 'saver' requires me to input a string for the name of the setting, which isn't too much work. However, I'm starting to expand the system, and I'm going to be saving tens if not hundreds of objects (not often though). Now, having to pass the name as a parameter is <em>very</em> tricky now, because I'm using <code>for</code> loops, so unless I want to create a new list for the names, I need a better method.</p>
  
  <p>EDIT (Added example of what I want):</p>
  
  <pre><code>    void LogName(object obj)
  {
  
      Debug.Log(GetNameOfParam(obj));
      DoStuff();
  }
  LogName(ObjectToSave);
  </code></pre>
  
  <p>This should log "ObjectToSave" not "obj"</p>
  
  <p>I've tried many different solutions:<br>
  <code>obj.GetType().Name</code>, which simply outputs the Type name<br>
  <code>nameof(obj)</code>, which outputs "obj"
  and even  </p>
  
  <pre class="lang-cs prettyprint-override"><code>public static string GetName&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; expr)
      {
          MemberExpression body = ((MemberExpression)expr.Body);
          string name = body.Member.Name;
          //object value = ((FieldInfo)body.Member).GetValue(((ConstantExpression)body.Expression).Value);
          return name;
      }
      GetName(() =&gt; obj)
  </code></pre>
  
  <p>which gives me "obj" as well.  </p>
  
  <p>EDIT (Added code):
  Overwrite code:</p>
  
  <pre><code>private void OverwriteObject(object obj)
  {
      string name = obj.GetType().Name;
      Debug.Log($"GetType.Name:{obj.GetType().Name}");
      Debug.Log($"nameof:{nameof(obj)}");
      Debug.Log($"GetName&lt;T&gt;:{ObjectExtensions.GetName(() =&gt; obj)}");
  
      string path = Paths.SettingsSaveLocation + Paths.SettingFilePrefix + name + Paths.SettingFileSuffix;
      //If setting file exist, read it
      if (File.Exists(path))
      {
          try
          {
              using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
              {
                  //Create buffer and read data
                  byte[] data = new byte[fs.Length];
                  fs.Read(data, 0, (int)fs.Length);
                  //Load data into setting object
                  JsonUtility.FromJsonOverwrite(Encoding.UTF8.GetString(data), obj);
              }
          }
          catch (Exception e)
          {
              Debug.LogException(e);
          }
      }
      //Otherwise, create a new one
      else
      {
          WriteObj(name, obj);
      }
  }
  </code></pre>
  
  <p>Write code:</p>
  
  <pre><code>    private void WriteObject(string name, object obj)
  {
      string path = Paths.SettingsSaveLocation + Paths.SettingFilePrefix + name + Paths.SettingFileSuffix;
      using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
      {
          //Use prettyPrint so it looks nicer
          string data = JsonUtility.ToJson(obj, true);
          fs.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);/**/
      }
  }
  </code></pre>
  
  <p>For loop (incomplete, needs work):</p>
  
  <pre><code>foreach (var obj in GameObject.FindGameObjectsWithTag("Enemy"))
      {
          WriteObject("Object name is xyzasd123", obj);
      }
  </code></pre>