简体   繁体   English

获取实例名称c#

[英]Get instance name c#

Maybe, this question is stupid, but in my specific situation i want to get instance name, so what i mean : 也许,这个问题很愚蠢,但在我的具体情况下,我想得到实例名称,所以我的意思是:

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

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

     public getInstanceName() 
     {
        //some function
     }

}

so when i make an student 所以,当我做一个学生

   Student myStudent = new Student("John");

it's stupid but i want this 这是愚蠢但我想要这个

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

This is now possible in C# 6.0: 现在可以在C#6.0中使用它:

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

This is useful for Code Contracts and error logging as it means that if you use "myStudent" in your error message and later decide to rename "myStudent", you will be forced by the compiler to change the name in the message as well rather than possibly forgetting it. 这对于代码约定和错误记录非常有用,因为这意味着如果在错误消息中使用“myStudent”并稍后决定重命名“myStudent”,编译器将强制您更改消息中的名称,而不是可能会忘记它。

This is not possible in C#. 这在C#中是不可能的。 At runtime, the variable names will not even exist, as the JIT removes the symbol information. 在运行时,变量名称甚至不存在,因为JIT删除了符号信息。

In addition, the variable is a reference to the class instance - multiple variables can reference the same instance, and an instance can be referenced by variables of differing names throughout its lifetime. 此外,变量是对类实例的引用 - 多个变量可以引用同一个实例,并且实例可以在其生命周期中由不同名称的变量引用。

This question is very old, but the answer changed with the release of .Net Framework 4.6. 这个问题非常陈旧,但答案随着.Net Framework 4.6的发布而改变。 There is now a nameof(..) operator which can be used to get the string value of the name of variables at compile time. 现在有一个nameof(..)运算符,可用于在编译时获取变量名称的字符串值。

So for the original question C# nameof(myStudent) // returns "myStudent" 所以对于原始问题C# nameof(myStudent) // returns "myStudent"

Give this a try 试一试

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

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

Or 要么

GetName(new { myStudent });

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}

Variable names exist only for your benefit while coding. 变量名称仅用于编码时的好处。 Once the the code is compiled, the name myStudent no longer exists. 编译代码后,名称myStudent不再存在。 You can track instance names in a Dictionary, like this: 您可以在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"

No, but you could do this 不,但你可以做到这一点

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

So I've been searching around for about a week trying to figure out how to do this. 所以我一直在寻找约一个星期试图找出如何做到这一点。 While gathering bits and pieces of stuff I didn't know I found a relatively simple solution. 在收集一些我不知道的东西时,我发现了一个相对简单的解决方案。

I think the original poster was looking for something like this, because if you have to use the name of the class to find out the name of the class then what's the point.. 我认为原始海报正在寻找类似的东西,因为如果你必须使用类的名称来找出类的名称,那么重点是什么。

For those saying "It's not possible" and "Why would you want to.." my particular reason is for a class library where I have a class that the app developer can call the instances whatever they want, and it's meant to have multiple instances with different names. 对于那些说“它不可能”和“你为什么要...”的人,我的特殊原因是我有一个类库,应用程序开发人员可以随意调用实例,并且它意味着有多个实例有不同的名字。 So I needed a way to be able to identify those instances so I can use the right one for the circumstance. 因此,我需要一种方法来识别这些实例,以便我可以使用正确的实例。

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

It does require that they pass in the name of the instance as I've not yet figured out how to acquire the name they're using from inside the constructor. 它确实要求它们传入实例的名称,因为我还没有弄清楚如何从构造函数中获取它们正在使用的名称。 That is likely the thing that isn't possible . 这很可能这是不可能的事情。

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

This creates the instance, stores a reference to it in Packets and saves it's name in the newly created instance. 这将创建实例,在Packets中存储对它的引用,并将其名称保存在新创建的实例中。

To get the name associated with the Packet and connect it to a variable.. 获取与Packet关联的名称并将其连接到变量..

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

Whether you use the same variable name or a new one doesn't really matter, it's just linking the instance you want to it. 无论您使用相同的变量名称还是新变量名称并不重要,它只是将您想要的实例链接到它。

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

For instances with the same name you would have to come up with some other way to tell them apart, which would require another list and some logic to determine which one you want. 对于具有相同名称的实例,您必须提出一些其他方法来区分它们,这需要另一个列表和一些逻辑来确定您想要哪一个。

No, this is not possible, because it's totally ridiculous. 不,这是不可能的,因为它完全是荒谬的。 An object can never, in any way, know the name of the variable you happen to assign it to. 对象永远不会以任何方式知道您将其分配给的变量的名称。 Imagine: 想像:

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

Should it say myStudent or anotherStudent ? 它应该说myStudent还是其他anotherStudent Obviously, it has no clue. 显然,它没有任何线索。 Or funnier situations: 或者更有趣的情况:

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

I really would like to know what this would print out. 我真的很想知道这会打印出来的是什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM