0

I'm working on Unity, using C#, and I made up a script that would make my life simpler if I could access constants using string variables.

public class Foo
{
    public const string FooConst = "Foo!";
    public const string BarConst = "Bar!";
    public const string BazConst = "Baz!";
}

// ...inside some method, somewhere else
public string Bar(string constName)
{
    // is it possible to do something like this?
    // perhaps with reflections?
    return Foo.GetConstant(constName);
}

My only solution was to create a method that gets the constant inside a switch. But every time I add a new constant, I have to modify that switch.

Fun fact: I'm a PHP kid that moved into C#. I like it is pretty strict, strong-typed and stuff... but that also makes things unnecessarily complicated.

5
  • Either name your constant-Variable like the constant-string -or- use a dictionary Commented Jan 10, 2015 at 15:46
  • possible duplicate of Getting variable by name in C# Commented Jan 10, 2015 at 15:51
  • Can you describe a problem, you're solving? You can do what you need with a help of reflection, but it's very strange construction for static-typed language. Commented Jan 10, 2015 at 15:52
  • @walther that question asks how to get a property, not a constant. In that solution, you require an instance. In this case, I suppose I don't need an instance since I'm trying to access constants. Commented Jan 10, 2015 at 15:57
  • 1
    Well, it's usually a bad idea either way. Static typing ensures you don't try to access things that don't exist, that you try to work with right variables and types etc. You try to avoid that and rely on string names instead. You should rethink your architecture, because php is very bad in that regard. Dump the things you've learned during php period and focus on how to develop software with C# the right way. Don't try to do the same things, because it will usually end up badly. Commented Jan 10, 2015 at 16:33

4 Answers 4

2

This uses reflection:

var value = typeof ( Foo ).GetFields().First( f => f.Name == "FooConst" ).GetRawConstantValue();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for providing your solution. I would just use FirstOrDefault instead of First. When you use First and the field does not exists, it throws an exception, with FirstOrDefault you get a null value, if the field is not present!
1

You could certainly do that using reflection, but IMHO a better option would be to store the constants in a dictionary or some other data structure. Like so:

public static class Foo
{
    private static Dictionary<string,string> m_Constants = new Dictionary<string,string>();

    static Foo()
    {
        m_Constants["Foo"] = "Hello";
        // etc
    }

    public static string GetConstant( string key )
    {
        return m_Constants[key];
    }
}

public string Bar( string constName )
{
    return Foo.GetConstant( constName );
}

Obviously this is a simplification. And it would throw an exception if you pass a key that doesn't exists etc.

2 Comments

My bad. I just looked at my code and I have used dictionaries already. The thing is that I have an enum so I could do this "myDict[MyEnum.SomeProp]". But I receive the name of the enum constant as string (string name = "SomeProp"). So my question was actually, How to get enum out of string? Uh, I should create a new Q. Although the other A's answered correctly (and I learned things), yours led to the right way.
@renocor Enum.Parse
1

you could try in this way with reflection

var constExample= typeof(Foo).GetFields(BindingFlags.Public | BindingFlags.Static |
               BindingFlags.FlattenHierarchy)
    .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.Name==constName).FirstOrFefault();

where constName is the constant that you are looking for

Refere here for documentation about property of FieldInfo.

As you can see I have filtered for IsLiteral = true and IsInitOnly = false

  • IsLiteral:

Gets a value indicating whether the value is written at compile time and cannot be changed.

  • IsInitOnly:

Gets a value indicating whether the field can only be set in the body of the constructor.

Comments

1

Yes, you have to use Reflection. Like this:

public string Bar(string constName)
{
    Type t = typeof(Foo);
    return t.GetField(constName).GetValue(null));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.