开发者

C#, variable value as a part of an object name?

开发者 https://www.devze.com 2023-01-31 19:33 出处:网络
For example i have a player object with a list of suits of cards it has. player.card[0] = \"diamonds\";

For example i have a player object with a list of suits of cards it has.

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

also i have 4 hidden pictureboxes with an image of suites ( pb_spades , pb_hearts m etc. )

and another 4 pictureboxs ( pb_playerCard1 , pb_开发者_如何学GoplayerCard2 , etc. ) to which I have to assign an image from a hidden pb corresponding to the suit of card the player object has.

Therefor

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

of course, doing it all with IFs would take quite a long time... Can I somehow use variable value as a part of an objects name?

kinda

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


Create a class Suite that has all properties, like this:

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

and then create a static object for each color:

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

 }

Now you can use Suite.Diamonds.

Even better is to use a Flyweight pattern to avoid the static fields. You use the Flyweight to implement the Card class.


First, there's no reason to have a hidden PictureBox control just so you can use it's Image property to store an image. Just create Image objects.

You could store the images in a dictionary, indexable by name:

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

Then instead of this:

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

You would write:

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

This code is still not great (any time you see variables like foo1, foo2, foo3, you should be putting those in an array so they can be indexed by number). The next step might be to refactor the code so you have something like:

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

Or:

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


I don't think that you can use a value as a part of the control name. But, one can use an aray of controls. You will have to change many declarations and initializations of your picture boxes and put them into an array, but you will be able to write more descriptive and readable code.


thanks again guys, I got it working using a List to store card suites for the player objects and a dictionary that stores image references.

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


The main class Player and the associated enumeration should be like this:


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

    public IList Cards { get; private set; }
}

enum CardType
{
    Diamond,
    Club,
    Spade,
    Heart
}

Another method GetPictureBox() should in the winform partial class


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

Use this method in the class using the player instance.


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

Finally the assignment to the image property, 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; } }


No, not how you're doing it, and although similar things can be achieved with reflection, what you want here is probably closer to just using FindControl for the "pb_playerCard" part and a simple dictionary of type Dictionary<CardSuitEnum, WhateverTheTypeOfImageIs> which you can populate with the pb_diamonds.Image etc.

Apols, I don't know what type .Image holds and can't be bothered to look it up :)

0

精彩评论

暂无评论...
验证码 换一张
取 消