Search code examples
c#oopconsole-applicationencapsulation

How can I hide a class member from other objects of the same type?


I'm writing a card game program in C#. I have a Player class, and each player can store multiple cards. For simplicity sake let's say that each Player has two cards, the VisibleCard and the HiddenCard. The VisibleCard is something everyone can see - imagine it's a card you play on the table. The HiddenCard is something only the player can see - i.e. it's what the player would hold in their hand.

I want to restrict the HiddenCard field so that only the Player object whom it belongs to can read it, and all other Player objects cannot. In other words, I want to encapsulate these fields on the object-level, not the class-level.

I've written a cursory attempt to implement this behaviour, but I'm wondering if there is a neater or more elegant way to do this in C#, or whether this approach has any holes in it?

class Program
{
    sealed class Player
    {
        public string Name;

        private string VisibleCard { get; }

        private string HiddenCard { get; }

        public Player(string name, string visibleCard, string hiddenCard)
        {
            Name = name;
            VisibleCard = visibleCard;
            HiddenCard = hiddenCard;
        }

        public void ReadPlayerCard(Player otherPlayer)
        {
            Console.Write("\n{0}'s hidden card: ", otherPlayer.Name);
            if (this == otherPlayer)
                Console.WriteLine(otherPlayer.HiddenCard);
            else
                Console.WriteLine("You can't see that.");

            Console.Write("{0}'s visible card: ", otherPlayer.Name);
            Console.WriteLine(otherPlayer.VisibleCard);

        }
    }

    static void Main(string[] args)
    {
        Player Alice = new Player("Alice", "Seven of Diamonds", "Four of Clubs");
        Player Bob = new Player("Bob", "Queen of Hearts", "Ace of Spades");

        Console.WriteLine("Bob is reading Alice's cards:");
        Bob.ReadPlayerCard(Alice);

        Console.WriteLine("\nAlice is reading Alice's cards:");
        Alice.ReadPlayerCard(Alice);

        Console.ReadLine();
    }
}

Leading to this result:

Bob is reading Alice's cards:  

Alice's hidden card: You can't see that.                                                                                
Alice's visible card: Seven of Diamonds                                                                                                                                                                                                         

Alice is reading Alice's cards:                                                                                                                                                                                                                 

Alice's hidden card: Four of Clubs                                                                                      
Alice's visible card: Seven of Diamonds 

So it does work, but I'm wondering: are there any ways that this could be exploited? The class is sealed so it can't be inherited, but I'm not sure whether this is the most straightforward approach to encapsulate members from other objects of the same type.

Any suggestions?


Solution

  • Access modifiers purpose

    The purpose of all access modifiers is to help a fellow programmer* from doing stuff with the class he is not supposed to do. They do not offer security in any way, shape or form.

    And you should not overuse them. Way too often a unessesary acessor forced programmers to rewrite a entire library from scratch - because they need that one piece that for no sensible reason was marked as private.

    Security in Multiplayer Games

    The first security level in multiplayer games, is to not display information the user is not supposed to have. The only way to circumvent that would be direct memory access. Access modifiers in no way, shape or form make that attack harder.

    The 2nd security level in multiplayer games is to not transmit information to the client programm in the first place. No memory access can retreive information that is not there. Access modifiers again do not help in any way I can imagine.

    *This fellow programmer could be your future self. The reason why you should write commentents, is that in 1-6 months you will have completely forgotten everything about that code. So you yourself might be the one that needs this guidance from his past self - or has to relearn the whole class from scratch.