14

也许,这个问题很愚蠢,但在我的具体情况下,我想获得实例名称,所以我的意思是:

class Student
{
     private string name {get; private set;}

     public Student(string name) 
     {
         this.name = name 
     }

     public getInstanceName() 
     {
        //some function
     }

}

所以当我让学生

   Student myStudent = new Student("John");

这很愚蠢,但我想要这个

 myStudent.getInstanceName(); // it should return 'myStudent'
4

8 回答 8

19

这现在可以在 C# 6.0 中实现:

Student myStudent = new Student("John");
var name = nameof(myStudent); // Returns "myStudent"

这对于代码合同和错误日志记录很有用,因为这意味着如果您在错误消息中使用“myStudent”,然后决定重命名“myStudent”,编译器将强制您更改消息中的名称,而不是可能会忘记它。

于 2015-08-24T01:15:49.190 回答
10

这在 C# 中是不可能的。在运行时,变量名甚至不存在,因为 JIT 删除了符号信息。

此外,变量是对类实例的引用——多个变量可以引用同一个实例,并且一个实例可以在其生命周期内被不同名称的变量引用。

于 2013-05-03T16:40:46.000 回答
5

这个问题很老了,但是随着 .Net Framework 4.6 的发布,答案发生了变化。现在有一个nameof(..)运算符可用于在编译时获取变量名称的字符串值。

所以对于原始问题C# nameof(myStudent) // returns "myStudent"

于 2016-09-20T22:45:35.217 回答
4

试试这个

string result = Check(() => myStudent);

static string Check<T>(Expression<Func<T>> expr)
{
    var body = ((MemberExpression)expr.Body);
    return body.Member.Name;
}

或者

GetName(new { myStudent });

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}
于 2013-05-03T16:41:15.110 回答
1

不,但你可以这样做

var myStudent = new Student("John").Named("myStudent");
var nameOfInstance = myStudent.Name();

public static class ObjectExtensions
{
    private static Dictionary<object,string> namedInstances = new Dictionary<object, string>(); 

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

    public static string Name<T>(this T obj)
    {
        if (namedInstances.ContainsKey(obj)) return namedInstances[obj];
        return obj.GetType().Name;
    }
}
于 2014-02-17T14:04:01.800 回答
1

变量名的存在只是为了您在编码时的利益。编译代码后,名称myStudent不再存在。您可以在 Dictionary 中跟踪实例名称,如下所示:

var students = new Dictionary<string, Student>();
var students["myStudent"] = new Student("John");

// Find key of first student named John
var key = students.First(x => x.Value.Name == "John").Key; // "myStudent"
于 2013-05-03T16:43:45.470 回答
1

所以我一直在寻找大约一个星期,试图弄清楚如何做到这一点。在收集一些我不知道的东西时,我找到了一个相对简单的解决方案。

我认为原始海报正在寻找这样的东西,因为如果您必须使用类名来找出类名,那有什么意义..

对于那些说“不可能”和“你为什么要......”的人,我特别的原因是一个类库,我有一个类,应用程序开发人员可以随意调用实例,它意味着有多个实例用不同的名字。所以我需要一种能够识别这些实例的方法,以便我可以针对具体情况使用正确的实例。

    public static List<Packet> Packets = new List<Packet>();
    public class Packet
    {
        public Packet(string Name)
        {
            Packets.Add(this);
            name = Name;
        }
        internal string _name;
        public string name
        {
            get { return _name; }
            set { _name = value; }
        }
    }

它确实需要它们传递实例的名称,因为我还没有弄清楚如何从构造函数内部获取它们正在使用的名称。这很可能是不可能的事情。

    public Packet MyPacket = new Packet("MyPacket");

这将创建实例,将对其的引用存储在 Packets 中,并将其名称保存在新创建的实例中。

获取与数据包关联的名称并将其连接到变量..

    Packet NewName = Packets[Packets.FindIndex(x => x.name == "MyPacket");

无论您使用相同的变量名还是新的变量名并不重要,它只是将您想要的实例链接到它。

    Console.WriteLine(NewName.name); // Prints MyPacket

对于具有相同名称的实例,您必须想出一些其他方法来区分它们,这需要另一个列表和一些逻辑来确定您想要哪个。

于 2019-03-15T17:51:29.800 回答
-2

不,这是不可能的,因为这完全荒谬。一个对象永远不可能知道你碰巧分配给它的变量的名称。想象:

Student myStudent = new Student("John");
Student anotherStudent = myStudent;
Console.Write(anotherStudent.getInstanceName());

应该说myStudent还是anotherStudent?显然,它没有任何线索。或者更有趣的情况:

School mySchool = new School("Harvard");
mySchool.enroll(new Student("John"));
Console.Write(mySchool.students[0].getInstanceName());

我真的很想知道这会打印出什么。

于 2013-05-03T16:41:12.240 回答