C#,变量值作为对象名称的一部分?

时间:2010-12-21 10:06:04

标签: c# winforms

例如,我有一个玩家对象,上面有一套卡片。

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; }

当然,使用IF完成所有操作需要相当长的时间......我能以某种方式使用变量值作为对象名称的一部分吗?

有点儿

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

6 个答案:

答案 0 :(得分:1)

创建一个包含所有属性的类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 pattern来避免静态字段。您使用Flyweight来实现Card类。

答案 1 :(得分:1)

首先,没有理由拥有隐藏的PictureBox控件,因此您可以使用它的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;

答案 2 :(得分:1)

我认为您不能将值用作控件名称的一部分。但是,人们可以使用一种控制。您将不得不更改图片框的许多声明和初始化并将它们放入数组中,但您将能够编写更具描述性和可读性的代码。

答案 3 :(得分:1)

再次感谢大家,我使用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]];
    }

答案 4 :(得分:0)

不,不是你是怎么做的,虽然通过反射可以实现类似的事情,但你想要的更接近于只使用FindControl作为“pb_playerCard”部分和一个简单的类型字典Dictionary<CardSuitEnum, WhateverTheTypeOfImageIs>,您可以使用pb_diamonds.Image等填充。

Apols,我不知道是什么类型的.Image持有并且不能费心去查找它:)

答案 5 :(得分:0)

主类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);

最后分配给image属性, 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; } }