Finding the variable name passed to a function

前端 未结 17 1947
广开言路
广开言路 2020-11-22 04:11

Let me use the following example to explain my question:

public string ExampleFunction(string Variable) {
    return something;
}

string WhatIsMyName = "         


        
相关标签:
17条回答
  • 2020-11-22 05:00

    GateKiller, what's wrong with my workaround? You could rewrite your function trivially to use it (I've taken the liberty to improve the function on the fly):

    static string sMessages(Expression<Func<List<string>>> aMessages) {
        var messages = aMessages.Compile()();
    
        if (messages.Count == 0) {
            return "";
        }
    
        StringBuilder ret = new StringBuilder();
        string sType = ((MemberExpression)aMessages.Body).Member.Name;
    
        ret.AppendFormat("<p class=\"{0}\">", sType);
        foreach (string msg in messages) {
            ret.Append(msg);
            ret.Append("<br />");
        }
        ret.Append("</p>");
        return ret.ToString();
    }
    

    Call it like this:

    var errors = new List<string>() { "Hi", "foo" };
    var ret = sMessages(() => errors);
    
    0 讨论(0)
  • 2020-11-22 05:04

    No. I don't think so.

    The variable name that you use is for your convenience and readability. The compiler doesn't need it & just chucks it out if I'm not mistaken.

    If it helps, you could define a new class called NamedParameter with attributes Name and Param. You then pass this object around as parameters.

    0 讨论(0)
  • 2020-11-22 05:04

    The short answer is no ... unless you are really really motivated.

    The only way to do this would be via reflection and stack walking. You would have to get a stack frame, work out whereabouts in the calling function you where invoked from and then using the CodeDOM try to find the right part of the tree to see what the expression was.

    For example, what if the invocation was ExampleFunction("a" + "b")?

    0 讨论(0)
  • 2020-11-22 05:06

    System.Environment.StackTrace will give you a string that includes the current call stack. You could parse that to get the information, which includes the variable names for each call.

    0 讨论(0)
  • 2020-11-22 05:06

    Well Try this Utility class,

    public static class Utility
    {
        public static Tuple<string, TSource> GetNameAndValue<TSource>(Expression<Func<TSource>> sourceExpression)
        {
            Tuple<String, TSource> result = null;
            Type type = typeof (TSource);
            Func<MemberExpression, Tuple<String, TSource>> process = delegate(MemberExpression memberExpression)
                                                                        {
                                                                            ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
                                                                            var name = memberExpression.Member.Name;
                                                                            var value = ((FieldInfo)memberExpression.Member).GetValue(constantExpression.Value);
                                                                            return new Tuple<string, TSource>(name, (TSource) value);
                                                                        };
    
            Expression exception = sourceExpression.Body;
            if (exception is MemberExpression)
            {
                result = process((MemberExpression)sourceExpression.Body);
            }
            else if (exception is UnaryExpression)
            {
                UnaryExpression unaryExpression = (UnaryExpression)sourceExpression.Body;
                result = process((MemberExpression)unaryExpression.Operand);
            }
            else
            {
                throw new Exception("Expression type unknown.");
            }
    
            return result;
        }
    
    
    }
    

    And User It Like

        /*ToDo : Test Result*/
        static void Main(string[] args)
        {
            /*Test : primivit types*/
            long maxNumber = 123123;
            Tuple<string, long> longVariable = Utility.GetNameAndValue(() => maxNumber);
            string longVariableName = longVariable.Item1;
            long longVariableValue = longVariable.Item2;
    
            /*Test : user define types*/
            Person aPerson = new Person() { Id = "123", Name = "Roy" };
            Tuple<string, Person> personVariable = Utility.GetNameAndValue(() => aPerson);
            string personVariableName = personVariable.Item1;
            Person personVariableValue = personVariable.Item2;
    
            /*Test : anonymous types*/
            var ann = new { Id = "123", Name = "Roy" };
            var annVariable = Utility.GetNameAndValue(() => ann);
            string annVariableName = annVariable.Item1;
            var annVariableValue = annVariable.Item2;
    
            /*Test : Enum tyoes*/
            Active isActive = Active.Yes;
            Tuple<string, Active> isActiveVariable = Utility.GetNameAndValue(() => isActive);
            string isActiveVariableName = isActiveVariable.Item1;
            Active isActiveVariableValue = isActiveVariable.Item2;
        }
    
    0 讨论(0)
提交回复
热议问题