我正在寻找一种方法将不同的选项作为参数传递给方法。 假设用户可以选择6个选项中的任何一个或全部,或者选择它们的任何子集。 所以他可以选择所有选项,只有选项1,2和& 4,只有选项1,3,5和& 6等...
如何有效地传递这个?
我正在考虑使用Enum,因为你可以进行按位添加,但是我错过了从那里开始的下一个难题:
然后我的方法会变成:
public void Foo(byte selectedOptions)
{
// How do I check whether an option has been selected??
if (selectedOptions >= Option.Whatever) DoThis();
}
所以你看到我有点坚持按位比较,我想知道这是否是正确的方式......
我不想做的是:
public void Foo(bool option1Selected, bool option2Selected, etc...);
想法?
答案 0 :(得分:6)
使用enum Flags
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
要选择多个选项,请使用按位或
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
要检查是否选择了标志,请使用按位和
if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
// Do something
}
答案 1 :(得分:1)
用户参数关键字:
public void Foo(params string[] options);
然后你可以将无限的字符串参数传递给函数,并在string []数组中读取它们。
或使用枚举(恕我直言是更好的方式):
[Flags]
public enum MyEnum {
Value1 = 1,
Value2 = 2,
Value3 = 4,
Value4 = 8,
Value5 = 16,
Value6 = 32,
}
public void Foo(MyEnum value){
if (value & MyEnum.Value1 > 0){
// we have Value1 passed
}
}
并将其称为:
Foo(MyEnum.Value1 | MyEnum.Value4 | MyEnum.Value10);
枚举值不应该是顺序的 - 如1,2,3,4,5,但是标志值 - 2 ^ x。
答案 2 :(得分:0)
你想和你的旗帜
public void Foo(Option selectedOptions)
{
if ((selectedOptions & Option.Whatever)>0)
{
// whatever
}
}
您还应该使用[Flags]
例如:
[Flags]
public enum Option
答案 3 :(得分:0)
传统上有几种方法可以实现您所描述的内容。第一个是定义结构:
public class FooOptions
{
bool Fizz;
bool Buzz;
bool Boom;
}
...然后你的方法的调用者将传递一个实例,并将相应的字段设置为true。
标志枚举是另一种解决方案:
public enum FooOptions
{
Fizz = 1,
Buzz = 2,
Boom = 4,
}
...然后使用类似的东西进行测试:
if ((options & FooOptions.Fizz) == FooOptions.Fizz) { ... }
然而,现在,C#具有可选和命名的参数,这意味着您的最终方法(您不想做的那个)将是最明智的:
public void Foo(bool fizz = false, bool buzz = false, bool boom = false)
{
...
}
...然后您可以使用任何参数排列调用,例如:
Foo(fizz: true, boom: true);
Foo(buzz: true);
答案 4 :(得分:0)
您可以使用HashSet<YourEnum>
来保存一组选项。
public void Foo(HashSet<YourEnum> selectedOptions)
{
if(selectedOptions.Contains(YourEnum.Option1))
DoSomething();
}
仅使用enum
很好,但对我来说Contains()
方法是一种更易读的测试方法。