使用字符串变量访问常量
本文关键字:访问 常量 变量 字符串 | 更新日期: 2023-09-27 18:36:59
我正在使用 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 孩子。我喜欢它非常严格,强类型之类的东西...但这也使事情变得不必要地复杂。
这使用反射:
var value = typeof ( Foo ).GetFields().First( f => f.Name == "FooConst" ).GetRawConstantValue();
您当然可以使用反射来做到这一点,但恕我直言,更好的选择是将常量存储在字典或其他数据结构中。这样:
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 );
}
显然,这是一种简化。如果您传递不存在的密钥等,它会引发异常。
你可以尝试以这种方式进行反射
var constExample= typeof(Foo).GetFields(BindingFlags.Public | BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.Name==constName).FirstOrFefault();
其中constName
是您正在寻找的常量
有关FieldInfo属性的文档,请参阅此处。
如您所见,我已经过滤了IsLiteral
= 真和IsInitOnly
= 假
-
IsLiteral
:
获取一个值,该值指示该值是否在编译时写入 并且无法更改。
-
IsInitOnly
:
获取一个值,该值指示字段是否只能在正文中设置。 的构造函数。
是的,你必须使用反射。喜欢这个:
public string Bar(string constName)
{
Type t = typeof(Foo);
return t.GetField(constName).GetValue(null));
}