0

Im trying to get the class variable name

static void Main()
{
    TaskAction m_first = new TaskAction();
    m_first.Increment();
    m_first.Increment();

    TaskAction m_Second = new TaskAction();
    m_Second.Increment();

}

public class TaskAction
{
    private int m_Current;

    public TaskAction()
    {
        m_Current = 0;

    }

    public void Increment()
    {
        m_Current++;
        write(" TaskAction " + vairableName + " "  + m_Current);       
    }
}

i want to it to write out:

TaskAction m_first 1

TaskAction m_first 2

TaskAction m_second 1

  • 4
    You can't, variable names are not compiled into assemblies. A bigger question though: why would you even want to do this? – DavidG Aug 30 '19 at 12:30
  • You cannot do this from inside of the `TaskAction` class. – dymanoid Aug 30 '19 at 12:30
  • 2
    You can't do this? What is the problem you're trying to solve? – Sean Aug 30 '19 at 12:31
  • trying to improve logging system – Anthony Brown Aug 30 '19 at 12:38
  • 1
    why not provide the variables name as argument to the constructor of `TaskActon`? Btw.: what would you expect, when a suer used `new TaskAction().Increment()`? Then the instance being created is not even assigned to a variable at all, so getting a name is pointless here. – MakePeaceGreatAgain Aug 30 '19 at 12:41
  • I agree with @HimBromBeere. Just give it a name (or id) in the constructor and use it internally to log. – JuanR Aug 30 '19 at 12:44
  • In the code you have posted, you know at compile time that the name is `m_Current` so why don't you hardcode it? – CodingYoshi Aug 30 '19 at 12:46
  • The class doesn't know where its instance is used/stored, as well as at run-time local variable names don't exists. All you seems need is to simply differentiate between two instances, either assign them name or let them to choose name by themselves (e.g. by using `private static` field which is incremented). – Sinatr Aug 30 '19 at 12:56
  • This doesn't help answer the question you ask (nothing can, really), but this is useful for logging: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/caller-information – Flydog57 Aug 30 '19 at 13:06

3 Answers3

2

Retrieving metadata about your program like that is both complex and unnecessary, just add the name by passing it to the constructor.

static void Main()
{
    TaskAction m_first = new TaskAction("m_first");
    m_first.Increment();
    m_first.Increment();

    TaskAction m_Second = new TaskAction("m_Second");
    m_Second.Increment();

}

public class TaskAction
{
    private int m_Current;
    private string m_taskName;

    public TaskAction(string taskName)
    {
        m_taskName = taskName;
        m_Current = 0;
    }

    public void Increment()
    {
        m_Current++;
        write(" TaskAction " + m_taskName + " "  + m_Current);       
    }
}
Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
0

Short Answer: You can't.

Long Answer:

Technically, it's possible to determine a variable name by inspecting the IL (the intermidate language created by the C# compiler), but this operation is hard and error-prone. Also, you ignore some important questions:

  • First of all, as already asked here: Why? how such thing will enhance your program?

  • Each instance of the class can have multiple variables pointing to it (see my answer about types in .NET here). Which of them you want to get? For example, consider the following program:

var v1 = new TaskAction();
var c2 = new TaskAction();
c1.Increment(); // 1 c1
c2 = c1;
c2.Increment(); // 2 c1? 2 c2? 2 c1 c2?
  • By doing so, you break the encapsulation in a difficult way - any reflection breaks the encapsulation, and really don't use it unless you really need it - but so much? Reflection breaks the hidden information about the private interface, you question breaks the internal interface!

Since you didn't give enough information, I can't know why you tought you need that. But here is some solutions:

  • If you want, for example, logging with categories - simply pass the category to the constructor, as sugegsted above.

  • If you want to know which type the variable is - using its name is very very very bad approach, even though you have conventions - use polymorphism instead (best), or, at least, check the type with is/as, for example:

if (this is Drived)
{
    ((Drived)this).SomeDrivedMethod();
}

Note that it breaks the OOP principles: a class shouldn't know about its drived classes.

Hope this helped you. Have a nice day!

Edit:

For your purpose, you can do one of the following:

Best - debug your code, see the call stack etc.

Worse - print the caller method name, instead of the object name. It's can be done using System.Runtime.CompilerServices.CallerMemberNameAttribute:

void Increment([System.Runtime.CompilerServices.CallerMemberName] string caller = null)
{
    // Default value to `caller` is neccessary
    // ...
    Console.WriteLine("Caller: {0}", caller);
}

Note: the compiler fills the caller parameter, not in runtime.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • the full TaskAction gets called in a lot of places, so i want to keep track when the Increment() gets called , as these get called in callbacks. I wanted an easy way to figure out how, when they get called, – Anthony Brown Aug 30 '19 at 14:10
-3

Get object.GetHashCode() if you want to uniquely identify class object or provide name to class by using custom constructor.

  • 1
    Hashcodes are not ment to be unique. Apart from this, your solution doesn´t seem like what OP wants to achieve. – MakePeaceGreatAgain Aug 30 '19 at 12:40
  • As per your comment "why not provide the variables name as argument to the constructor of TaskActon?" is what i meant by "provide name to class by using custom constructor." – nanda kumar gowda Aug 30 '19 at 12:55