简体   繁体   English

将不同的选项传递给方法

[英]Passing Different Options to a Method

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. 假设用户可以选择6个选项中的任何一个或全部,或它们的任何子集。 So he could choose all options, only option 1, 2 & 4, only option 1, 3, 5 & 6 etc... 因此,他可以选择所有选项,仅选择选项1、2和4,仅选择选项1、3、5和6,等等。

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. 那么您可以将无限的字符串参数传递给该函数,并在string []数组中读取它们。

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. 枚举值不应是连续的-像1,2,3,4,5,而标志值应是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] 您还应该用[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. ...,然后您的方法的调用者将传递一个实例并将适当的字段设置为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: 但是,如今,C#具有可选参数和命名参数,这意味着最明智的最终方法(您不想做的一种):

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. 您可以使用HashSet<YourEnum>来保存一组选项。

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. 仅使用enum就可以了,但是对我来说, Contains()方法是测试选项的更具可读性的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM