如何为参数设置定义的值?我的意思是,例如,我有以下功能:
int functionA(string parameterA) {}
现在,当我调用此函数并为参数 A 输入值时,我希望该值位于我定义的值集中。例如,定义的值集是:
string[] definedParameterA = { "Hello World", "stackoverflow" };
我输入的 parameterA 的值必须是“Hello World”或“stackoverflow”。
如何为参数设置定义的值?我的意思是,例如,我有以下功能:
int functionA(string parameterA) {}
现在,当我调用此函数并为参数 A 输入值时,我希望该值位于我定义的值集中。例如,定义的值集是:
string[] definedParameterA = { "Hello World", "stackoverflow" };
我输入的 parameterA 的值必须是“Hello World”或“stackoverflow”。
如果你真的希望它是一个字符串,你只需在方法的开头验证它:
private static readonly String[] ValidValues = {"Hello World", "stackoverflow"};
public void DoSomething(string text)
{
if (!ValidValues.Contains(text))
{
throw new ArgumentException("Invalid value: " + text, "text");
}
// Carry on
}
但是,您也可以考虑改用枚举。您仍然需要验证枚举值是否已定义,但它使调用者更容易正确处理:
public enum Message
{
HelloWorld,
StackOverflow
}
public void DoSomething(Message message)
{
if (!Enum.IsDefined(typeof(Enum), message))
{
throw new ArgumentException("Invalid value: " + message, "message");
}
// Carry on
}
当然,如果需要,您可以将枚举值映射到其他地方的字符串。
请注意,上面的代码将message
在每次调用时装箱。如果你真的想要,你可以使用我的Unconstrained Melody项目来避免这种情况(并使其更安全),但在你证明这种拳击实际上是一个问题之前,它可能不值得。代码将如下所示:
public void DoSomething(Message message)
{
if (!message.IsNamedValue()) // Extension method
{
throw new ArgumentException("Invalid value: " + message, "message");
}
// Carry on
}
也许静态类可以帮助您。
public static class MyValidParameters
{
public static const string HelloWorld = "Hello World";
public static const string Stackoverflow = "stackoverflow";
//
}
因此,您可以拥有任何类型的复杂参数(不仅是字符串),并且可以在不同的静态类中管理它们。
我想用最笼统的术语改写 John Skeet 的回答:
您正在使用字符串。字符串是一种无界类型,可以包含几乎无限的可能值范围,从莎士比亚的全集null
到""
莎士比亚的全部作品。如果您只期望少数可能的值,那么无限数据类型可能不是您的正确选择。也许您可以将其替换为有界数据类型?
正如 John Skeet 所示,系统中内置的最简单的有界数据类型是 Enums。它们提供了一组封闭的可能值。所以你得到你的输入,将它映射到值列表中,然后从现在开始使用它。但是,有一些并发症。第一个是 John Skeet 提到的可能的性能惩罚。第二个是不是所有的字符串都可以表示为 Enum 值。例如,“Hello World”不是有效的 C# 标识符,因此很难将其映射到枚举中。
这可以通过使用[Description("Hello world")]
or[DisplayName("Hello world")]
属性装饰枚举值并使用反射来匹配它来完成,但这有其自身的性能损失。在这种情况下,您可能会考虑使用某种静态实用程序将字符串映射到枚举值。