Сопоставить два значения одному объекту - PullRequest
3 голосов
/ 02 августа 2010

Я пытаюсь написать функцию на C #, которая будет принимать два небольших значения типа int (диапазон 0-3) и возвращать объект Color на основе этих значений. Проблема в том, что нет способа программно определить цвет по двум значениям, они специфичны для типа светодиода и должны быть жестко закодированы.

Самым простым способом, который я могу придумать, было бы массивное (16 случаев) выражение if-else, которое проверяет каждое значение, но это не выглядит как очень элегантное решение. Есть ли лучший способ определить цвет?

Ответы [ 7 ]

2 голосов
/ 02 августа 2010

А как насчет двумерного массива объектов Color?

Color[,] colors = new[,] {
    { Color.FromArgb(1, 2, 3), Color.FromArgb(3, 4, 5), Color.FromArgb(6, 7, 8), Color.FromArgb(9, 10, 11) },
    { Color.FromArgb(21, 22, 23), Color.FromArgb(23, 24, 25), Color.FromArgb(26, 27, 28), Color.FromArgb(29, 30, 31) },
};

Color color = colors[index1, index2];
2 голосов
/ 02 августа 2010

Если вы хотите использовать ОО-подход (к лучшему или к худшему), вы можете использовать Tuple-> Color mapping:

Dictionary<Tuple<int, int>, Color> d = new Dictionary<Tuple<int, int>, Color>()
{
  {Tuple.Create(2, 1), Color.Red},
  {Tuple.Create(1, 1), Color.Blue},
  {Tuple.Create(1, 2), Color.Green}
};

Одно преимущество перед двумерным массивом состоит в том, что он может быть разреженным без нулей. Вы также можете использовать инициализатор коллекции без инициализации в порядке индекса. Это приведет к явному ArgumentException во время инициализации, если вы попытаетесь использовать один и тот же кортеж для двух цветов.

1 голос
/ 02 августа 2010

В качестве немного более чистой альтернативы использованию if / else вы можете поместить значения цвета в массив и использовать два небольших значения типа int в качестве индексов в массиве.

0 голосов
/ 02 августа 2010

Тот факт, что у вас есть эти два небольших целочисленных значения, которые объединяются, чтобы что-то значить (по крайней мере, цвет), подсказывает мне, что для вас может иметь смысл определить структуру, инкапсулирующую их.

Преимущество этого состоит в том, что вы можете использовать структуру в качестве ключа к словарю: методы Equals и GetHashCode уже должны работать адекватно.

Ниже приведен пример. Поскольку вы упомянули, что цвета не могут быть рассчитаны, я оставил комментарий, в котором необходимо заполнить словарь; Вы можете жестко закодировать это, но в идеале вы должны прочитать значения из файла или встроенного ресурса.

РЕДАКТИРОВАТЬ: обновил мой пример структуры, чтобы быть неизменным.

struct MyStruct
{
    private byte _X;
    private byte _Y;

    public MyStruct(byte x, byte y)
    {
        _X = x;
        _Y = y;
    }

    public byte X { get { return _X; } }
    public byte Y { get { return _Y; } }

    private static Dictionary<MyStruct, Color> _ColorMap;

    static MyStruct()
    {
        _ColorMap = new Dictionary<MyStruct, Color>();

        // read color mapping from somewhere...perhaps a file specific to the type of LED
    }

    public Color GetColor()
    {
        return _ColorMap[this];
    }
}
0 голосов
/ 02 августа 2010

Как насчет:

static Color GetColor(int c1, int c2)
{
  if (c1 > 3 || c1 < 0 || c2 > 3 || c2 < 0)
    throw new ArgumentOutOfRangeException();

  var map = new Dictionary<string, Color>
  {
    {"00", Color.Black},
    {"10", Color.Red},
    {"20", Color.Blue},
    // etc, etc...
    {"11", Color.DimGray},
  };

  var key = c1.ToString() + c2.ToString();
  return map[key];
}
0 голосов
/ 02 августа 2010

Я голосую за 16 цветов

enum Color
{
    red = 0,
    blue = 1
}

public Color GetColor(int v1, int v2)
{
    int colorValue = v1 << 8;
    colorValue |= v2;
    return (Color)colorValue;
}
0 голосов
/ 02 августа 2010

Предпочтительный способ избежать кучу операторов if else - использовать Switch.Вы также можете использовать enum и присваивать значения типа int, которые соответствуют вашим маленьким целым числам:

public enum ColorChoice
{
  red = 01 //'01' instead of '1' to make clear your first digit is zero
  blue = 02
  green = 03
  ...etc...
]
...