4

Is this possible!!?!?!?!?

I'm trying to make a set of classes that model a number of different types of things. Properties of these things change over time, and I want my code to be easy to maintain, so I want to do something like the following:

public class Cat
{
    public string CatName { get; set; }

    public Cat()
    {
        this.CatName = MAGICSTUFF.GetInstanceName(this);
     }

}

Somewhere else, when I want to get at those cats, I want to be able to say:

[TestMethod]
public void test_awesome_cats()
{
    Cat Tiger = new Cat();
    Assert.IsTrue(Tiger.CatName.Equals("Tiger"));
}

So, I'm trying to map my naming convention into object properties. The part I can't figure out is the MAGICSTUFF.GetInstanceName. Is that a thing?

I suspect this is impossible, so if that's the case hopefully somebody can give me some other ideas on clever ways to use convention for this type of scenario. I've been thinking of using attributes for the Cat class for a while, but I like this was a lot better if its possible.

thebeekeeper
  • 364
  • 2
  • 12

4 Answers4

4

It's not possible to do that kind of reflection. Variable names could be erased by the compiler depending on debugging options and scope. The name of a variable is an alias of its "address" so can not be reversed (at least in Java and C# AFAIK).

An object can be pointed from nay variables, so the variable name is irrelevant and the object don't know this kind of stuff:

Cat tiger = new Cat();
Cat tiger2 = tiger;

Variable tiger2 points to the Cat "tiger", so 2 variable points same object with different names.

Use class properties passed in the constructor.

David Oliván
  • 2,717
  • 1
  • 19
  • 26
  • Do you know if it's possible in any other language? I've moved past my idea of solving my problem this way, but I'm still interested in whether or not its possible. – thebeekeeper Sep 12 '11 at 14:20
  • I know well C, C++, Java and .NET and it's not possible. Variable names are alias of the memory addresses of the variables and they are erased in code; code (machine/assembler, bytecode) uses the memory address directly. When debugging, a table symbol coverts the memory address to the variable name in order to allow evaluating live expressions and so on. – David Oliván Sep 12 '11 at 21:39
  • I've moved passed this issue, but I think this response makes why it's impossible the most clear, so I'll mark this as the anwer. – thebeekeeper May 05 '12 at 05:10
2

The normal way of doing this is to store the 'name' as a variable in the instance, for ex:

// Initialize this like: var cat = new Cat("Tiger");
class Cat {
    public String Name { get; private set; }
    public Cat(String name) 
    { 
        Name = name; 
    }
}

And then if you need to get tigers in more than one place, make it into a method that explicitly returns Tigers:

// This can go into a class of cat-creating static methods.  Or maybe in the Cat class itself.
public static Cat GiveMeATiger() {
    return new Cat("Tiger");
}
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
1

Given the question as is, It is would be very hard, if not impossible, to do so.

With debugging symbols, it is possible to dig up through stack frames and enumerate the local variables and match the address with the instance address. However, the approach won't work because the constructor will be invoked before the reference got set, so the tiger will be null at the time and matching will fail all the time.

Yet if I can alter the question, the solution might be that you need to call MAGICSTUFF.GetInstanceName(this); in getter method of CatName instead, so my approach should be working fine.

Now I'm trying to writing some code to do so, though I would post it here if someone might read this and come up with the real implementation before me.

tia
  • 9,518
  • 1
  • 30
  • 44
-1

I know, I know, old post.

but I found a solution...

public static List<Packet> Packets = new List<Packet>();
public class Packet
{
    public Packet()
    {
        Packets.Add(this);
    }
    public string packetName;
}

public Packet myPacket = new Packet();
myPacket.packetName = "myPacket";

public void SomeMethod()
{
    int x = 0;
    foreach (Packet p in Packets)
    {
        if (p.packetName = "myPacket")
        {
            Packet myPacket = Packets[x];
            break;
        }
        x++;
    }
}
KSummers
  • 32
  • 4