使用字符串变量访问常量

时间:2015-01-10 15:42:40

标签: c#

我正在使用C#开发Unity,并且我编写了一个脚本,如果我可以使用字符串变量访问常量,那将使我的生活变得更简单。

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);
}

我唯一的解决方案是创建一个在switch内获取常量的方法。但每次添加新常量时,我​​都要修改switch

有趣的事实:我是一个移植到C#的PHP孩子。我喜欢它非常严格,强类型和东西......但这也使事情变得不必要地复杂化。

4 个答案:

答案 0 :(得分:1)

是的,你必须使用Reflection。像这样:

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

答案 1 :(得分:1)

你当然可以使用reflection来做到这一点,但恕我直言更好的选择是将常量存储在字典或其他数据结构中。像这样:

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 );
}

显然这是一种简化。如果你传递一个不存在的密钥等,它会抛出异常。

答案 2 :(得分:1)

这使用反射:

var value = typeof ( Foo ).GetFields().First( f => f.Name == "FooConst" ).GetRawConstantValue();

答案 3 :(得分:1)

你可以用这种方式尝试反思

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

其中constName是您要查找的常量

请参阅here以获取有关FieldInfo属性的文档。

如您所见,我已针对IsLiteral = true和IsInitOnly = false

进行了过滤
  • IsLiteral
  

获取一个值,该值指示是否在编译时写入值   并且无法改变。

  • IsInitOnly
  

获取一个值,该值指示是否只能在正文中设置该字段   构造函数。