将单个阵列与多个不同的阵列进行比较

时间:2015-07-27 14:27:10

标签: c# process switch-statement logic affinity

对于processor affinity上的小项目,我想创建一个更简单的方法,而不仅仅是一堆if(lvProcessors.Items[0].Checked == true && lvProcessors.Items[1] == true etc)比较它们的确切值,以查看哪些代码需要转移到(IntPtr)

为了使代码更有效率,我想将包含booleans的数组与至少14个包含booleans的其他数组进行比较。

示例代码:

        var CheckState = new[] { lvProcessors.Items[0].Checked, lvProcessors.Items[1].Checked, lvProcessors.Items[2].Checked, lvProcessors.Items[3].Checked };
        //setcore1 == 1, setcore2 == 2, etc
        var SetCore1 = new[] { true, false,false,false };
        var SetCore2 = new[] { true, true, false, false };
        var SetCore3 = new[] { false, true, false, false };
        var SetCore4 = new[] { true, false, true, false };
        var SetCore5 = new[] { false, true, true, false };
        var SetCore6 = new[] { true, true, true, false };
        var SetCore7 = new[] { false, false, false, true };
        var SetCore8 = new[] { true, false, false, true };
        var SetCore9 = new[] { false, true, false, true };
        var SetCore10 = new[] { true, true, false, true };
        var SetCore11 = new[] { false, false, true, true };
        var SetCore12 = new[] { true, false, true, true };
        var SetCore13 = new[] { false, true, true, true };
        var SetCore14 = new[] { true, true, true, true };
        int switchcounter = 1;

        switch (switchcounter)
        {
            case 15:
                break;
            default:

                if (Enumerable.SequenceEqual(CheckState,<insertdynamicarrayname))
                {
                    AffinityState = (IntPtr)switchcounter;
                }
                else
                {
                    switchcounter++;
                    goto default;
                }
                break;
        }

因此,如果选中checkbox中的第一个listview lvProcessorsvar CheckState将生成包含{ true, false,false,false }的数组

这又必须与其中一个SetCore数组进行比较,在这种情况下会导致与SetCore1匹配。

所以我想知道的是;如何根据代码上的switchcounter创建动态arrayname,它会融合"SetCore"switchcounter.ToString(),从而创建SetCore1, SetCore2, SetCore3, etc

[编辑]

正如@Luaan所建议的那样,我已经将他的代码实现到我希望的样式:

        var SetCore1 = new[] { true, false, false, false};
        [..]
        var SetCore15 = new[] { true, true, true, true };
        var allSets = new [] { SetCore1, SetCore2, SetCore3,SetCore4,SetCore5,SetCore6,SetCore7,SetCore8,SetCore9,SetCore10,SetCore11,SetCore12,SetCore13,SetCore14,SetCore15 };

        foreach (var set in allSets)
        {
            MessageBox.Show(counter.ToString());
            if (Enumerable.SequenceEqual(set, CheckState))
            {
                AffinityState = (IntPtr)counter;
                break;
            }
            else if (Enumerable.SequenceEqual(set, CheckState) == false) 
            {
                counter++;
            }
        }
        EditProcess.ProcessorAffinity = (IntPtr)AffinityState;

在此代码中,根据listviewcheckboxes的输入,它会将相关结果与SetCore相匹配,并使用counter它会提供正确的intforeach循环结束时转换并设置非常特定的核心(即1,2或0,2,3等),用于之前选择的所选process在代码中(不可见)。

感谢关于位掩码的建议,它们看起来很有用,但目前我不知道如何在不将我的应用程序分开的情况下实现它们。

1 个答案:

答案 0 :(得分:0)

只需创建一个数组数组:

var allSets = new [][] { SetCore1, SetCore2, SetCore3, ... }

然后你可以使用一个简单的循环:

for (var i = 0; i < allSets.Length; i++)
   HandleSet(allSets[i]);

使用Enumerable.SequenceEqual会有点慢。如果你关心表演(我不认为你必须在这样的情况下做),看看BitArray - 它的内存要小得多,而且匹配大多是简单的bitmasking。

修改

如果您想在bool[]int(或byte之间转换,无论您需要什么),您可以使用以下内容:

public bool[] ToBoolArray(int val)
{
  var bits = new bool[sizeof(int) * 8];

  for (var i = 0; i < bits.Length; i++)
  {
    bits[i] = (val & (1 << i)) > 0;
  }

  return bits;
}

public int ToInt32(bool[] bits)
{
  var output = default(int);

  for (var i = 0; i < bits.Length; i++)
  {
    output |= bits[i] ? 1 << i : 0;
  }

  return output;
}

这避免了必须处理大量令人讨厌的字符串。使用BitArray这更简单 - 从BitArray创建int是微不足道的(那里是构造函数),并且可以轻松地将其更改回int如上所述,只需使用bits.Get(i)代替bits[i]

甚至更好,自己上课来处理这个问题:

public sealed class CpuMask
{
  private int _bits;

  public bool this[int index]
  {
    get { return (_bits & (1 << index)) > 0; }
    set { if (value) _bits |= (1 << index); else _bits &= ~(1 << index); }
  }

  public CpuMask(int mask)
  {
    _bits = mask;
  }

  public CpuMask(IntPtr mask) : this(mask.ToInt32()) { }

  public IntPtr ToIntPtr() { return new IntPtr(_bits); }
}