I'm looking for a way to pass different options as a parameter to a method. Let's assume that a user can choose any or all of 6 options or any subset of them. So he could choose all options, only option 1, 2 & 4, only option 1, 3, 5 & 6 etc...
How do I pass this around effectively?
I was thinking of using an Enum since you can do bitwise additions, but I'm missing the next pieces of the puzzle to go from there:
Could my method then become something like:
public void Foo(byte selectedOptions)
{
// How do I check whether an option has been selected??
if (selectedOptions >= Option.Whatever) DoThis();
}
So you see I'm kind of stuck on the bitwise comparisons and I wonder if this is even the right way...
What I don't want to do is:
public void Foo(bool option1Selected, bool option2Selected, etc...);
Ideas?
Go with enum Flags
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
For selecting multiple options use bitwise or
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
To check if a flag is selected use bitwise and
if ((testItem & FlagTest.Flag1) == FlagTest.Flag1)
{
// Do something
}
User params keyword:
public void Foo(params string[] options);
then you can pass unlimited string params to the function, and read them in the string[] array.
Or using enum(which IMHO is the better way):
[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
}
}
and call this as:
Foo(MyEnum.Value1 | MyEnum.Value4 | MyEnum.Value10);
Enum values should not be sequential - like 1,2,3,4,5, but flag values - 2^x.
You want to AND your flags
public void Foo(Option selectedOptions)
{
if ((selectedOptions & Option.Whatever)>0)
{
// whatever
}
}
You also should decorate your enum with [Flags]
eg:
[Flags]
public enum Option
Traditionally there were a couple of ways to achieve what you're describing. The first would be to define a struct:
public class FooOptions
{
bool Fizz;
bool Buzz;
bool Boom;
}
... and then the caller of your method would pass an instance of that with the appropriate fields set to true.
Flag enums were another solution:
public enum FooOptions
{
Fizz = 1,
Buzz = 2,
Boom = 4,
}
... which you'd then test using something like:
if ((options & FooOptions.Fizz) == FooOptions.Fizz) { ... }
Nowadays, however, C# has optional and named parameters, which means your final approach (the one you didn't want to do) would be the most sensible:
public void Foo(bool fizz = false, bool buzz = false, bool boom = false)
{
...
}
... which you could then call with any permutation of parameters, like:
Foo(fizz: true, boom: true);
Foo(buzz: true);
You can use HashSet<YourEnum>
to hold a set of options.
public void Foo(HashSet<YourEnum> selectedOptions)
{
if(selectedOptions.Contains(YourEnum.Option1))
DoSomething();
}
Using just enum
is fine but to me Contains()
method is more readable way of testing for an option.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.