2015-07-27 2 views
1

Для небольшого проекта на 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; 
     } 

Таким образом, если в listview lvProcessors первый checkbox установлен, var CheckState будет генерировать массив, содержащий { true, false,false,false }

Это, в свою очередь, должна быть по сравнению с одной из SetCore массивов, и в этом случае вызовет матч с SetCore1.

Так что я хотел бы знать; как я могу создать динамическое имя arrayname, основанное на коде switchcounter, которое будет скомбинировать "SetCore" и switchcounter.ToString(), создав таким образом SetCore1, SetCore2, SetCore3, etc.

[EDIT]

Как было предложено @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 он даст правильный int, который преобразуется в конце цикла foreach и устанавливает очень специфические сердечники (то есть 1, 2 или 0, 2, 3, и т. д.), которые будут использоваться для выбранных process whi ch был выбран ранее в коде (не видно).

Спасибо за предложение на битмаски, они выглядят полезными, но в настоящее время я понятия не имею, как их реализовать, не разделяя половину моего приложения.

+0

A [битовая] (http://stackoverflow.com/questions/3261451/using-a-bitmask-in-c-sharp) часто является более гибким способом хранения булевых комбинаций. –

+0

Вы пробовали использовать 2-мерный массив? – Graham

ответ

0

Просто сделайте массив массивов:

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

Затем вы можете использовать простой для цикла:

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

Использование Enumerable.SequenceEqual будет немного медленно. Если вы заботитесь о производительности (я не думаю, что вы обязательно это делаете в таком случае), посмотрите на BitArray - он намного меньше в памяти, и совпадение в основном представляет собой простое битовое маскирование.

EDIT:

Если вы хотите конвертировать между 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); } 
} 
+0

Это было то, что я искал, проблема в том, что вход очень точный для вывода. Например, 'SetCore1' приведет к тому, что сродство ядра будет таким же, как и Диспетчер задач Windows. Так что это только Core0. Если значение будет больше, чем количество ядер, 'intptr' будет в большой степени запутанным. Совпадение 'listviewcheckboxes' с внешним источником, доступным только на его собственном языке, довольно сложно. –

+0

@BRO_THOM Вы всегда можете использовать классы-оболочки, чтобы помочь вам обрабатывать данные сопоставления. И не волнуйтесь слишком много о «битАртри» - они в значительной степени предназначены для того, что вы делаете, но это не имеет большого значения. Вы даже можете использовать простые 'long's для всей маски сродства, это не такая уж большая работа, как доступ к массиву (и вам, как правило, не нужно будет обращаться к маске по частям). – Luaan

+0

Я на самом деле достаточно смел, чтобы просмотреть несколько методов, и тот, который я нашел наиболее полезным, подобен такому; значение массива 'CheckState' будет преобразовано в байты с использованием' Convert.ToByte', заполняющего «Список » (например, создание 00001111), который будет преобразован в десятичный код в цикле 'for', что приведет к ложному ложному ложному false true true true true для преобразования в десятичную цифру 15, что мне и нужно. –

Смежные вопросы