Правильный способ инициализации Enums внутри конструктора класса - PullRequest
1 голос
/ 05 октября 2011

Я могу смотреть на Enums неправильно, но хочу убедиться, что у меня есть правильная теория о том, как их использовать.

Скажем, у нас есть перечисление с именем Color.

enum Colour { Red, Green, Blue };

Красный Зеленый и Синий представлены значениями 0-255.Я пытаюсь инициализировать это перечисление внутри формы класса, и я не совсем уверен, как это сделать.

public class Shape
{

    Colour colour;

    public Shape(Colour c)
    {
         //Some attempts at initialization.


         //Treating It like an object
         this.colour = 
            c{
                255,255,255
            };

         //Again
         this.colour.Red = c.Red
         this.colour.Blue = c.Blue
         this.colour.Green = c.Green

         Colour.red = c.red?


         }
    }
}

Я, вероятно, далек от того, как я думаю о перечислениях,Кто-нибудь может дать мне несколько советов?

Ответы [ 7 ]

4 голосов
/ 05 октября 2011

В этом случае вы можете захотеть, чтобы цвет был struct вместо перечисления.В C # перечисления являются однозначными конструкциями, но у вас есть три значения (красное, зеленое и синее).Вот что я мог бы сделать вместо этого:

public struct Colour 
{
    private byte red;
    private byte green;
    private byte blue;

    public Colour(byte r, byte g, byte b) 
    {
        this.red = r;
        this.green = g;
        this.blue = b;
    }
}

public class Shape
{
    public Colour Colour { get; private set; }

    public Shape(Colour c)
    {
        this.Colour = c;
    }
}

А затем, когда вы создаете свои объекты-фигуры:

var shape = new Shape(new Colour(203, 211, 48));

РЕДАКТИРОВАТЬ : Как указал Крисв комментариях вы можете просто использовать структуру System.Drawing.Color, предоставляемую фреймворком.Приведенный выше пример будет упрощен до:

using System.Drawing;

public class Shape
{
    public Color Colour { get; private set; }

    public Shape(Color c)
    {
        this.Colour = c;
    }
}

var shape = new Shape(Color.FromArgb(203, 211, 48));
1 голос
/ 05 октября 2011

Перечисление очень похоже на таблицу типов (или ассоциаций) в реляционной базе данных.Это набор параметров, позволяющий ограничить значение.Подумайте о enum как о «списке выбора», возможно, если вы не так хорошо разбираетесь в реляционных базах данных.Перечисления дают нам небольшой конечный список вариантов для переменной, тогда как базовый тип (int, byte и т. Д.) Намного больше.

Обычный метод для выполнения того, что вы пытаетесь - это проверить значение перечислениязатем настройте свой объект:

switch(c)
{
   case Colour.Red:
        //Set up red shape here
        break;
   //etc ...
}
0 голосов
/ 05 октября 2011

Если цвет - это ваше перечисление, то все, что вам нужно сделать в конструкторе, это сказать:

this.colour = c;

Однако меня немного смущает и беспокоит ваш комментарий о том, что "красный, зеленый и синий представлены значениями 0-255". большинство цветов будет иметь значение для каждого из красного, зеленого и синего, поэтому вам не нужно просто перечислять.

Перечисление легче всего представить по аналогии с выпадающим списком. Существует множество фиксированных значений, и ваш выбор должен быть одним из них, а не другим. За раскрывающимся списком может быть значение, но обычно вы хотите знать, говорит ли раскрывающийся список «Красный» или нет, а не то, какое значение за ним. Причина этого в том, что обычно в Enums вы просто говорите «If (color = Colour.Red) then ....».

То, что вы делаете, звучит больше похоже на .NET Class Color (названный американцами, возможно, поэтому вы его не нашли, если это то, что вы хотите). У него есть свойства для R, G, B, а также набор статических свойств, которые будут возвращать предопределенные экземпляры класса Color (например, Color.Red) и возвращать экземпляр Color с соответствующим набором RGB.

Так что я думаю, что вы, возможно, ошиблись в конце Enums, и, возможно, вам нужен класс Color.

Последнее, что вам может понадобиться, это иметь какой-нибудь класс Factory, который выполняет что-то вроде:

public Color CreateColor(Colour colEnum)
{
    switch(colEnum)
    case Colour.Red:
    return Color.Red;
    etc.
}

(извинения за путаницу в именах и использование цвета и цвета)

Это может гарантировать, что вы получите цвета, основанные на вашем перечислении, и только цвета, определенные в вашем перечислении, могут быть созданы таким образом.

0 голосов
/ 05 октября 2011

Возможно, type-safe enum - это то, что вы ищете. Они допускают гораздо более богатое поведение, чем стандартные перечисления.

public sealed class Colour
{
  public int RedComponent { get; private set;}
  public int GreenComponent { get; private set;}
  public int BlueComponent { get; private set;}

  public static readonly Colour Red = new Colour(255,0,0);

  private Colour(int red, int green, int blue)
  {
    RedComponent = red;
    GreenComponent = green;
    BlueComponent = blue;
  }
}

Затем вы можете иметь метод Foo(Colour c){//Do something with c.RedComponent etc.} и вызывать Foo(Colour.Red)

Вы даже можете сравнивать значения в соответствии с обычным перечислением:

Bar(Colour c)
{
  return c == Colour.Red;
}
0 голосов
/ 05 октября 2011

Лучше всего с неизменной структурой:

public struct Colour
{
    private readonly byte red;

    private readonly byte green;

    private readonly byte blue;

    public Colour(byte red, byte green, byte blue)
    {
        this.red = red;
        this.green = green;
        this.blue = blue;
    }

    public byte Red
    {
        get
        {
            return this.red;
        }
    }

    public byte Green
    {
        get
        {
            return this.green;
        }
    }

    public byte Blue
    {
        get
        {
            return this.blue;
        }
    }
}

Вы бы инициализировали его так:

Shape shape = new Shape(new Colour(104, 255, 67));
0 голосов
/ 05 октября 2011

Ваше перечисление Colour не имеет свойств для каждого определенного вами значения перечисления. Значения Red, Green и Blue являются значениями, которыми может быть ваше перечисление .

Вы хотите сделать что-то вроде this.colour = Colour.Red, чтобы установить для вашей переменной colour значение red. Затем, позже в коде, если вы хотите запустить какой-то код только на основании того, было ли значение красным или нет, вы можете сделать что-то вроде:

if(this.colour == Colour.Red)
{
// Do red specific logic
}
0 голосов
/ 05 октября 2011
this.colour = Colour.Red; // or Colour.Green or whatever

this.colour имеет тип Colour и может принимать только одно из трех значений.Думайте о Colour как о типе, подобном Integer, но он может принимать только одно из трех значений, в то время как Integer может принимать любое из значений в диапазоне Integer.MIN_VALUE..Integer.MAX_VALUE.

Если вы пытаетесь создатьRGB цвет из этого, тогда это не правильный подход.В этом случае вы ищете класс с именем Colour, который имеет различные значения для своих компонентов red, green and blue.

...