C #, значение переменной как часть имени объекта? - PullRequest
1 голос
/ 21 декабря 2010

Например, у меня есть объект игрока со списком мастей карт, который у него есть.

player.card[0] = "diamonds"; 
player.card[1] = "clubs"; 
player.card[2] = "spades"; 
etc...

также у меня есть 4 скрытых фотобокса с изображением комплектов (pb_spades, pb_hearts m и т. Д.)

и еще 4 ящика для картинок (pb_playerCard1, pb_playerCard2 и т. Д.), Которым я должен назначить изображение из скрытого pb, соответствующее масти карты, которую имеет объект игрока.

Therefor

if ( player.card[0] == "diamonds" ) { pb_playerCard1.Image = pb_diamonds.Image; }

конечно, выполнение всего этого с IFs займет довольно много времени ... Могу ли я как-то использовать значение переменной как часть имени объекта?

любопытное

for (int i = 1; i != 5; i++)
{
pb_playerCard+'i'.Image = pb_+'player.card[i+1]'.Image;
}

Ответы [ 6 ]

1 голос
/ 21 декабря 2010

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

Dictionary<CardType, System.Drawing.Image> newDeckImages = new Dictionary<CardType, System.Drawing.Image>();

...

        newDeckImages.Add(CardType.Diamonds, pb_diamonds.Image);
        newDeckImages.Add(CardType.Hearts, pb_hearts.Image);
        newDeckImages.Add(CardType.Clubs, pb_clubs.Image);
        newDeckImages.Add(CardType.Spades, pb_spades.Image);

...

        private void showMyCards()
    {

        pb_termCard1.Image = newDeckImages[Terminator.cards[0]];
        pb_termCard2.Image = newDeckImages[Terminator.cards[1]];
        pb_termCard3.Image = newDeckImages[Terminator.cards[2]];
        pb_termCard4.Image = newDeckImages[Terminator.cards[3]];
    }
1 голос
/ 21 декабря 2010

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

1 голос
/ 21 декабря 2010

Во-первых, нет необходимости иметь скрытый элемент управления PictureBox, просто вы можете использовать его свойство Image для хранения изображения. Просто создайте объекты Image.

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

  var cards = new Dictionary<string, Image>() { 
     { "diamonds", Image.FromFile("diamonds.jpg") }
     { "clubs",    Image.FromFile("clubs.jpg") }
     //...
  };

Тогда вместо этого:

if ( player.card[0] == "diamonds" ) { pb_playerCard1.Image = pb_diamonds.Image; }

Вы бы написали:

pb_playerCard1.Image = images[player.card[0]];

Этот код все еще не очень хорош (каждый раз, когда вы видите переменные, такие как foo1, foo2, foo3, вы должны помещать их в массив, чтобы их можно было индексировать по номеру). Следующим шагом может быть рефакторинг кода, чтобы у вас было что-то вроде:

pb_playerCard[0].Image = images[player.card[0]];

Или:

pb_playerCard[0].Image = player.card[0].Image;
1 голос
/ 21 декабря 2010

Создайте класс Suite, который имеет все свойства, например:

class Suite {
   public string Name { get; set; }
   public Image Image { get; set; }

, а затем создайте статический объект для каждого цвета:

   public static Diamonds = new Suite { Name = "Diamonds", Image = Resources.DiamondImage };
   // ...

 }

Теперь вы можете использовать Suite.Diamonds.

Еще лучше использовать шаблон Flyweight , чтобы избежать статических полей. Вы используете Flyweight для реализации класса Card.

0 голосов
/ 21 декабря 2010

Основной класс Player и соответствующее перечисление должны выглядеть следующим образом:


class Player
{
    public Player(int n)
    {
        Cards = new List(n);
    }

    public IList Cards { get; private set; }
}

enum CardType
{
    Diamond,
    Club,
    Spade,
    Heart
}

Другой метод GetPictureBox () должен использоваться в частичном классе winform


public PictureBox GetPictureBox(string pictureBoxName)
{
    if(this.Controls.ContainsKey(pictureBoxName))
    {
        Control control = this.Controls[pictureBoxName];
        PictureBox pictureBox;
        if ((pictureBox = control as PictureBox) != null)
        {
            return pictureBox;
        }
    }

    return null;
}

Использовать этот метод вкласс с использованием экземпляра проигрывателя.


Player player = new Player(3);
player.Cards.Add(CardType.Diamond);
player.Cards.Add(CardType.Club);
player.Cards.Add(CardType.Spade);

Dictionary dictionary = new Dictionary();
dictionary.Add(CardType.Diamond, pb_diamonds);
dictionary.Add(CardType.Spade, pb_spades);
dictionary.Add(CardType.Club, pb_clubs);
dictionary.Add(CardType.Heart, pb_hearts);

Наконец, присваивание свойству изображения for (int i = 1; i < 5; i++) { string playercardPictureBoxName = string.Concat("pb_playercard", i.ToString()); PictureBox pictureBox = this.GetPictureBox(playercardPictureBoxName); if (pictureBox != null) { pictureBox.Image = dictionary[player.Cards[i - 1]].Image; } }

0 голосов
/ 21 декабря 2010

Нет, не то, как вы это делаете, и хотя подобные вещи могут быть достигнуты с помощью рефлексии, то, что вы хотите здесь, вероятно, ближе к простому использованию FindControl для части "pb_playerCard" и простого словарятипа Dictionary<CardSuitEnum, WhateverTheTypeOfImageIs>, который вы можете заполнить pb_diamonds.Image и т. д.

Apols, я не знаю, какой тип .Image содержит и не может быть обеспокоен, чтобы посмотреть его:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...