将枚举名称分配给常量变量
Assign Enum names to const variable
我目前正在尝试将特定枚举中的名称分配给一个字符串,以便我可以在输出到控制台的帮助文档中使用它。这很容易通过以下方式完成:
public string names = string.Join(", ", Enum.GetNames(typeof(LicenseType)));
我的问题是我使用的是 Command Line Parser Library,它需要将每个选项的帮助文本指定为属性参数 (HelpText
),它必须是 "constant expression, typeof expression or array creation expression of an attribute parameter type".如何使用 names
的示例:
[Option('t', "license-type", Required = true, HelpText = names)]
但是,当我尝试使用上面的代码将枚举名称分配给 const string
时,编译器抱怨表达式不是常量。
有什么解决办法吗?
枚举是编译时常量,但编译器不保证对 string.Join
的方法调用会产生常量值,因为它与 Enum.GetName
.
由于您的枚举是编译为常量,因此您需要将值硬编码到您的属性中。
问题是即使 enum
s 可能是编译时常量,任何 代码,包括上面实际获取这些名称的代码,都是 not 常数,因为它需要的评估不仅仅是简单的原始值。因此,不可能在需要 string
.
的 Attribute
中使用 enum
名称
但是,如果 OptionAttribute
不是 sealed
,您可以定义一个继承的 Attribute
class,它接受一个期望枚举的参数,然后通过上面的代码为base(string)
。使用此 Attribute
,库应将其视为 OptionAttribute
,即使您已将其传递给 enum
值。见以下代码:
public class EnumHelpTextAttribute // Always postpend the word "Attribute" to an attribute class
// The compiler cleans this suffix when you actually use the Attribute
: OptionAttribute
{
public EnumHelpTextAttribute(LicenseType value)
: base(string.Join(", ", Enum.GetName(typeof(LicenseType), value)))
{
}
}
// ...
[EnumHelpText(LicenseType.Restricted)] // Or some other value in LicenseType...
遗憾的是,已经注意到 OptionAttribute
class 是 sealed
,这会阻止创建继承者。然而,作为一个开源项目,可以分叉源代码,解封 class,并因此使用上述建议。一如既往,记录使用情况并返回一个 pull request - 有一天这可以很容易地为其他人省去麻烦!
昨晚睡了一觉之后,解决方案实际上很明显(不是总是这样吗!):只需使用字符串替换...
class Options
{
private static string LicenseTypeHelp = "License type (" + string.Join(", ", Enum.GetNames(typeof(CompanyLicenseType))) + ").";
[Option('t', "license-type", Required = true, HelpText = "License type.")]
public CompanyLicenseType LicenseType { get; set; }
[HelpOption('h', "help", HelpText = "Dispaly this help screen.")]
public string GetUsage()
{
string helpText = HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current));
return helpText.Replace("License type.", LicenseTypeHelp);
}
}
我目前正在尝试将特定枚举中的名称分配给一个字符串,以便我可以在输出到控制台的帮助文档中使用它。这很容易通过以下方式完成:
public string names = string.Join(", ", Enum.GetNames(typeof(LicenseType)));
我的问题是我使用的是 Command Line Parser Library,它需要将每个选项的帮助文本指定为属性参数 (HelpText
),它必须是 "constant expression, typeof expression or array creation expression of an attribute parameter type".如何使用 names
的示例:
[Option('t', "license-type", Required = true, HelpText = names)]
但是,当我尝试使用上面的代码将枚举名称分配给 const string
时,编译器抱怨表达式不是常量。
有什么解决办法吗?
枚举是编译时常量,但编译器不保证对 string.Join
的方法调用会产生常量值,因为它与 Enum.GetName
.
由于您的枚举是编译为常量,因此您需要将值硬编码到您的属性中。
问题是即使 enum
s 可能是编译时常量,任何 代码,包括上面实际获取这些名称的代码,都是 not 常数,因为它需要的评估不仅仅是简单的原始值。因此,不可能在需要 string
.
Attribute
中使用 enum
名称
但是,如果 OptionAttribute
不是 sealed
,您可以定义一个继承的 Attribute
class,它接受一个期望枚举的参数,然后通过上面的代码为base(string)
。使用此 Attribute
,库应将其视为 OptionAttribute
,即使您已将其传递给 enum
值。见以下代码:
public class EnumHelpTextAttribute // Always postpend the word "Attribute" to an attribute class
// The compiler cleans this suffix when you actually use the Attribute
: OptionAttribute
{
public EnumHelpTextAttribute(LicenseType value)
: base(string.Join(", ", Enum.GetName(typeof(LicenseType), value)))
{
}
}
// ...
[EnumHelpText(LicenseType.Restricted)] // Or some other value in LicenseType...
遗憾的是,已经注意到 OptionAttribute
class 是 sealed
,这会阻止创建继承者。然而,作为一个开源项目,可以分叉源代码,解封 class,并因此使用上述建议。一如既往,记录使用情况并返回一个 pull request - 有一天这可以很容易地为其他人省去麻烦!
昨晚睡了一觉之后,解决方案实际上很明显(不是总是这样吗!):只需使用字符串替换...
class Options
{
private static string LicenseTypeHelp = "License type (" + string.Join(", ", Enum.GetNames(typeof(CompanyLicenseType))) + ").";
[Option('t', "license-type", Required = true, HelpText = "License type.")]
public CompanyLicenseType LicenseType { get; set; }
[HelpOption('h', "help", HelpText = "Dispaly this help screen.")]
public string GetUsage()
{
string helpText = HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current));
return helpText.Replace("License type.", LicenseTypeHelp);
}
}