我正在使用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孩子。我喜欢它非常严格,强类型和东西......但这也使事情变得不必要地复杂化。
答案 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
:获取一个值,该值指示是否只能在正文中设置该字段 构造函数。