Добавление классов в список динамически со значениями перечисления - PullRequest
0 голосов
/ 23 сентября 2019

Я пытаюсь создать метод, который создает список объектов.Объекты добавляются со значениями перечислителя.

В настоящее время у меня есть 2 счетчика: CardType, CardColor.Назначение значения CardType работает как задумано, но когда я использую точно такой же код для присвоения CardColor, он всегда возвращает одно и то же значение (красный).

Я включил оператор switch, который я уже пробовал, в форме комментария.

Класс с основным методом:

 public class CardStack
        {
            Card CardObject;
            List<Card> cardList;
            public CardStack()
            {
                cardList = new List<Card>();
                CardObject = new Card();
            }
            public List<Card> getCardList()
            {     
                for(int i = 1; i <= Enum.GetNames(typeof(CardType)).Length; i++)
                {
                    CardObject.Type = addCardType(i);
                    for(int n =0; n <= 3; n++)
                    {

                        CardObject.Color = addCardColor(n);
                        cardList.Add(CardObject);
                    }

                    CardObject = new Card();
                }
                return cardList;
            }

            public CardColor addCardColor(int colorNumber)
            {
                //Debug.WriteLine(colorNumber.ToString());
                //switch (colorNumber)
                //{

                //    case 0: return CardColor.Green;
                //    case 1: return CardColor.Blue;
                //    case 2: return CardColor.Yellow;
                //    case 3: return CardColor.Red;                
                //    default:
                //        return CardColor.Yellow;
                //}
                return (CardColor)colorNumber;
            }
            public CardType addCardType(int typeNumber)
            {
                return (CardType)typeNumber;
            }

        }

Enum CardColor:

public enum CardColor
{
    Green,
    Blue,
    Yellow,
    Red
}

Enum CardType:

public enum CardType
{
   One = 1,
   Two = 2,
   Three = 3,
   Four = 4,
   Five = 5,
   Six = 6,
   Give_2,
   Take_1,
   Which
}

Мой отладочный вывод (сокращен):

 Type: One; Color: Red;
[0:] Type: One; Color: Red;
[0:] Type: One; Color: Red;
[0:] Type: One; Color: Red;
[0:] Type: Two; Color: Red;
[0:] Type: Two; Color: Red;
[0:] Type: Two; Color: Red;
[0:] Type: Two; Color: Red;
[0:] Type: Three; Color: Red;
[0:] Type: Three; Color: Red;
[0:] Type: Three; Color: Red;
[0:] Type: Three; Color: Red;

Ответы [ 3 ]

2 голосов
/ 23 сентября 2019
for(int i = 1; i <= Enum.GetNames(typeof(CardType)).Length; i++)
{
    CardObject.Type = addCardType(i);         // Sets Card Type
    for(int n =0; n <= 3; n++)
    {
        CardObject.Color = addCardColor(n);   //1. Sets Color on THE SAME CardObject
        cardList.Add(CardObject);             //2. Adds THE SAME CardObject 4 times
    }
    CardObject = new Card();                  //3. create new Object => all of the 
                                              // above added references point to
                                              // the same CardObject, which has 
                                              // been set to "Red".
}

Решение: переместить строку, помеченную // 3.во внутреннем цикле for, сразу после //2.

Не связано:

  • Я бы порекомендовал создать параметризованный конструктор, так что вы можете просто сделать cardList.Add(new Card(type, color)).
  • Поскольку тип и цвет карты не изменятся, они должны быть доступны только для чтения.На самом деле Card должно быть неизменным .
  • Просто используйте foreach для итерации значений перечисления .

Улучшенная версия:

public IEnumerable<Card> GetCardList()
{
    foreach (CardType type in Enum.GetValues(typeof(CardType)))
    {
        foreach (CardColor color in Enum.GetValues(typeof(CardColor)))
        {
            yield return new Card(type,color);
        }
    }
}

(см. yield контекстное ключевое слово)

Где Card:

public class Card
{
    public readonly CardType Type;
    public readonly CardColor Color;

    public Card( CardType type, CardColor color )
    {
        this.Type = type;
        this.Color = color;
    }
}
0 голосов
/ 23 сентября 2019

Используйте foreach для перебора значений перечисления.Создайте новый CardObject в каждом целом (внутренний цикл!) И добавьте их в список.

public class CardStack
{
    private readonly List<Card> _cardList;
    public CardStack()
    {
        _cardList = getCardList();

    }
    private static List<Card> getCardList()
    {
        var localList = new List<Card>();
        foreach (CardType type in Enum.GetValues(typeof(CardType)))
        {
            foreach (CardColor color in Enum.GetValues(typeof(CardColor)))
            {
                var cardObject = new Card(){Type = type, Color = color};
                localList.Add(cardObject);
            }
        }

        return localList;
    }
}
}
0 голосов
/ 23 сентября 2019

В своем текущем коде во внутреннем цикле вы изменяете свойства одного и того же экземпляра Card (CardObject), добавляя его в cardList.Это будет означать, что все ссылки будут иметь то же значение, что и цвет в последнем цикле, который в вашем случае будет красным.

Что вам нужно сделать, это повторно инициализировать CardObject во внутреннем цикле.Например,

for(int i = 1; i <= Enum.GetNames(typeof(CardType)).Length; i++)
{
    CardObject.Type = addCardType(i);
    for(int n =0; n <= 3; n++)
    {
         CardObject = new Card();   // Change here
         CardObject.Color = addCardColor(n);
         cardList.Add(CardObject);
    }
}

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

Между тем, другой подход для достижения того же самого с использованием Linq будет

var list = Enum.GetValues(typeof(CardType))
               .Cast<CardType>()
               .SelectMany(type => Enum.GetValues(typeof(CardColor))
                                       .Cast<CardColor>()
                                       .Select(color => 
                                        new Card {Type = type, Color = color}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...