Chris
Chris

Reputation: 22257

Is it possible to pass a variable's name along with the value, when passing through functions?

I want to know if it's possible to retrieve the variables name from when it was passed into a certain function. For example, if I call parseId(myId) to a function with the signature parseId(id), i can obviously retrieve the value of 'id'. However, is there any way I can retrieve 'myId' as a string (without passing it as another value)?

Specifically in vb.net, but I'm interested in how it would work in any given language.

Upvotes: 1

Views: 825

Answers (3)

Marc Gravell
Marc Gravell

Reputation: 1063298

This is all just random thoughts.. feel free to dismiss or not ;-p

Re your comment about use with stored procedures... if you want to go that route, I wouldn't mess around with the local variable names; that is an implementation detail. However, you could expose those details on an interface method and use the names from there, since that is more formalised - for example (C#):

interface ICustomerRepository {
    Customer GetById(int id); // perhaps an attribute to name the sproc
}

You can use similar expression-tree parsing (as discussed here) to get the name and value of the parameter, for example:

var repoWrapper = new Repo<ICustomerRepository>();
int custId = 12345;
var cust = repoWrapper.Execute(r => r.GetById(custId));

Here we'd want to resolve the argument to GetById as "id" (not "custId"), with value 12345. This is actually exactly what my protobuf-net RPC code does ;-p (just don't ask me to translate it to VB - it is hard enough to write it in a language you know well...)

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1063298

You can do this in .NET 3.5 and above using expression trees; I'll knock up a C# example, and try to run it through reflector for VB...

C#:

static void Main()
{
    int i = 17;
    WriteLine(() => i);
}
static void WriteLine<T>(Expression<Func<T>> expression)
{
    string name;
    switch (expression.Body.NodeType)
    {
        case ExpressionType.MemberAccess:
            name = ((MemberExpression)expression.Body).Member.Name;
            break;
        default:
            throw new NotSupportedException("Give me a chance!");
    }
    T val = expression.Compile()();
    Console.WriteLine(name + "=" + val);
}

The VB is below, but note that the VB compiler seems to use different names (like $VB$Local_i, not i):

Sub Main()
    Dim i As Integer = 17
    WriteLine(Function() i)
End Sub

Private Sub WriteLine(Of T)(ByVal expression As Expression(Of Func(Of T)))
    If (expression.Body.NodeType <> ExpressionType.MemberAccess) Then
        Throw New NotSupportedException("Give me a chance!")
    End If
    Console.WriteLine((DirectCast(expression.Body, MemberExpression).Member.Name
        & "=" & Convert.ToString(expression.Compile.Invoke)))
End Sub

Upvotes: 1

Joel Coehoorn
Joel Coehoorn

Reputation: 416011

No, you can't do that in the normal sense. What are you really trying to accomplish with this?

Upvotes: 1

Related Questions