.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;

public class Program
{
	public static void Main()
	{
		var obj1 = new Object();
		var obj2 = obj1;
		obj1.Named(() => obj1);
		obj2.Named(() => obj2);
		Console.WriteLine(obj1.Name());
		Console.WriteLine(obj2.Name());
		var obj3= new Object();
		//Console.WriteLine(obj3.Name()); //exception, by design
	}
	

	public Dictionary<string, string> nameOfAlreadyAcessed = new Dictionary<string, string>();
	public string nameOf(object obj, int level = 1)
	{
		StackFrame stackFrame = new StackTrace(true).GetFrame(level);
		string fileName = stackFrame.GetFileName();
		int lineNumber = stackFrame.GetFileLineNumber();
		string uniqueId = fileName + lineNumber;
		if (nameOfAlreadyAcessed.ContainsKey(uniqueId))
			return nameOfAlreadyAcessed[uniqueId];
		else
		{
			System.IO.StreamReader file = new System.IO.StreamReader(fileName);
			for (int i = 0; i < lineNumber - 1; i++)
				file.ReadLine();
			string varName = file.ReadLine().Split(new char[]
			{
			'(', ')'
			}

			)[1];
			nameOfAlreadyAcessed.Add(uniqueId, varName);
			return varName;
		}
	}
}

public static class ObjectInstanceExtensions
{
	private static Dictionary<object, string> namedInstances = new Dictionary<object, string>();
	public static void Named<T>(this T instance, Expression<Func<T>> expressionContainingOnlyYourInstance)
	{
		var name = ((MemberExpression)expressionContainingOnlyYourInstance.Body).Member.Name;
		instance.Named(name);
	}

	public static T Named<T>(this T instance, string named)
	{
		if (namedInstances.ContainsKey(instance))
			namedInstances[instance] = named;
		else
			namedInstances.Add(instance, named);
		return instance;
	}

	public static string Name<T>(this T instance)
	{
		if (namedInstances.ContainsKey(instance))
			return namedInstances[instance];
		throw new NotImplementedException("object has not been named");
	}
}
;