Highmastdon
Highmastdon

Reputation: 7520

Return a variable based on the input of a function (.NET C# or VB)

Say I've got the following variables:

Public Shared x As String = "100"
Public Shared y As String = "text"
Public Shared z As String = "something"

And I got a function:

Function giveVar(ByVal varName As String) As String 

    Return varName
End Function

But this doesn't do what I want, naturally. What I want is that my function giveVar returns the value of the variable that holds giveVar. For example I call giveVar("x") I want my function to return "100".

Of course this can be done by a Select Case but thats not what I like to do. Does anyone has any suggestion? Is it even possible to call a value based on a string?

[edit:]

Namespace i18n
    public NotInheritable Class Settings
        Public Shared LanguageCode As String
        Public Shared HideAllLocalizedText As Boolean
    End Class

Public NotInheritable Class i18n
        Private Sub New()

        End Sub

        Public Shared Function t(ByVal varName As String) As String
            Select Case Settings.LanguageCode
                Case "en"
                    Return en(varName)
                Case Else
                    Return nl(varName)
            End Select
        End Function

        Private Shared Function en(ByVal varName As String) As String
            Dim ASP_0344 As String = "Cancel"
            Dim ASP_0807 As String = "Click"
            Dim ASP_0808 As String = "here"
            Dim ASP_0812 As String = "Welcome at the login screen..."

            ' These are examples there is a whole bigger list               

            Return CallByName(Me, varName, vbGet)
        End Function

        Private Shared Function nl(ByVal varName As String) As String
            Dim ASP_0344 As String = "Annuleren"
            Dim ASP_0807 As String = "Klik"
            Dim ASP_0808 As String = "hier"
            Dim ASP_0812 As String = "Welkom op het inlogscherm..."

            Return CallByName(Me, varName, vbGet)
        End Function

    End Class
End Namespace

I think this works so far, BUT I get the following error on the CallByName(Me, varName, vbGet) at the Me : "me is only valid within an instance method"

Upvotes: 0

Views: 1095

Answers (5)

Tim M.
Tim M.

Reputation: 54378

The simplest implementation for what you are asking might be a Dictionary.

Example

// c#
var values = new Dictionary<string, string>();
values["x"] = "100";
values["y"] = "text";
values["z"] = "something";

public string GiveVar( string name )
{
   return values[name];
}
'vb.net
Dim values As New Dictionary(Of String, String)
values.Add("x", "100")
values.Add("y", "text")
values.Add("z", "something")

Function giveVar(ByVal varName As String) As String 
    Return values(varName)
End Function

At this point, you don't really need a function to get the value. You can just use the indexer on the dictionary.

Alternatively reflection can be used if the names of the members aren't known until runtime. Reflection carries a (sometimes substantial) performance hit and can lead to brittle/unintuitive code but--used correctly--is a powerful tool.

Expando objects can also be used to create similar code. Usually this isn't the right path unless you are using expando objects to improve less-structured data.

Upvotes: 3

Jodrell
Jodrell

Reputation: 35716

How about a generic solution

in c#

using System.Reflection;

public class MyClass
{
    public static string x = "1";
    public static int y = 2;

    public static bool TryGetValue<T>(string variableName, out T value)
    {
        try
        {
            var myType = typeof(MyClass);
            var fieldInfo = myType.GetField(variableName);
            value = (T)fieldInfo.GetValue(myType);
            return true;
        }
        catch
        {
            value = default(T);
            return false;
        }
    }
}

you can use like this

string xValue;
if (MyClass.TryGetValue("x", xValue))
{
    // it worked
}
else
{
    // oops, x is not there or it will not cast to string
}

int yValue;
if (MyClass.TryGetValue("y", yValue))
{
    // it worked
}
else
{
    // oops, x is not there or it will not cast to int
}

but remember, with

string valueX = MyClass.x;
int valueY = MyClass.y;

The code is shorter and you get type checking at compile time.

Upvotes: 0

L&#226;m Tran Duy
L&#226;m Tran Duy

Reputation: 814

Yes, you can do it using reflection:

Imports System.Reflection

Public Class Test

  Public Shared x As String = "100"
  Public Shared y As String = "text"
  Public Shared z As String = "something"

  Function giveVar(ByVal varName As String) As String

    Dim pi As FieldInfo = Me.GetType().GetField(varName)

    Return (pi.GetValue(Me)).ToString()

  End Function

End Class

To test it :

Module Module1

  Sub Main()

    Dim t As New Test

    Console.WriteLine("x: " & t.giveVar("x"))
    Console.WriteLine("y: " & t.giveVar("y"))
    Console.WriteLine("z: " & t.giveVar("z"))

    Console.ReadKey()

  End Sub

End Module

You need to import the System.Reflection namespace for this to work, also the variables need to be defined in the class where the giveVar() function is defined, otherwise you'll need to pass the objet that owns the variables as a parameter and replace the Me.GetType() call.

Lastly, this doesn't work with local variables.

Upvotes: 2

juergen d
juergen d

Reputation: 204756

Try

CallByName (Me, "x", VbGet)

Upvotes: 1

Jakub Konecki
Jakub Konecki

Reputation: 46008

Put your strings in a Hashtable and you can easily retrieve them by key. You can still have public properties that look up using hard-coded keys.

Upvotes: 0

Related Questions