Class that can read/modify private values of another class
-
Is there a way to write a class that can modify private values of another class? In this situation ... I have a table (a black box which contains methods like AddPlayer, RemovePlayer, DealNewHand) ... but I don't want to directly work with the values. I want to call only certain methods that will modify the table exactly how it should be modified. But ... I need to directy be able to read/modify some of those private values, for simulating play. I want to write a class Dealer which will be able directly read/modify some of those values. The dealer, for example, would be responsible for knowing who's turn it is to act (needs access to the private players objects stored in the table) and for updating the corresponding table values. So, is there a way for me to give the Dealer Class access to the private members of the Table class, or am I going to need to make the members of the table class that I want the dealer only to be able to see, public? As always, thanks!
-
Is there a way to write a class that can modify private values of another class? In this situation ... I have a table (a black box which contains methods like AddPlayer, RemovePlayer, DealNewHand) ... but I don't want to directly work with the values. I want to call only certain methods that will modify the table exactly how it should be modified. But ... I need to directy be able to read/modify some of those private values, for simulating play. I want to write a class Dealer which will be able directly read/modify some of those values. The dealer, for example, would be responsible for knowing who's turn it is to act (needs access to the private players objects stored in the table) and for updating the corresponding table values. So, is there a way for me to give the Dealer Class access to the private members of the Table class, or am I going to need to make the members of the table class that I want the dealer only to be able to see, public? As always, thanks!
C# doesn't have an equivalent to C++'s friend modifier. If you don't want to expose members of your table class outside of the namespace you are writing but would like other classes, namely your Dealer class, to be able to access them, you could make those members internal instead of private. Not quiet the same as C++'s friendship mechanism, but pretty close for many situations. However, it occurred to me that your table class looks very much like a collection. I would suggest creating a strongly typed collection class that implements the
ICollection
interface. The Dealer class could access the players in the collection through using an enumerator, or maybe an indexer property that you provide. As the Dealer enumerates through the Players, it can deal each one a new hand, or whatever. Does this make sense? -
C# doesn't have an equivalent to C++'s friend modifier. If you don't want to expose members of your table class outside of the namespace you are writing but would like other classes, namely your Dealer class, to be able to access them, you could make those members internal instead of private. Not quiet the same as C++'s friendship mechanism, but pretty close for many situations. However, it occurred to me that your table class looks very much like a collection. I would suggest creating a strongly typed collection class that implements the
ICollection
interface. The Dealer class could access the players in the collection through using an enumerator, or maybe an indexer property that you provide. As the Dealer enumerates through the Players, it can deal each one a new hand, or whatever. Does this make sense?Something you said, just made me question myself. All these classes are defined in the same namespace: PokerLib, and compiled as a class library. Are you saying that classes defined inside the same namespace CAN access private members of other classes defined in the same namespace?
-
Something you said, just made me question myself. All these classes are defined in the same namespace: PokerLib, and compiled as a class library. Are you saying that classes defined inside the same namespace CAN access private members of other classes defined in the same namespace?
budidharma wrote:
Are you saying that classes defined inside the same namespace CAN access private members of other classes defined in the same namespace?
Nope. I'm saying that if you use the
internal
modifier instead of theprivate
modified for class members, classes in the same assembly (I said namespace in my earlier post, but should have said assembly) will be able to access thoseinternal
members. -
budidharma wrote:
Are you saying that classes defined inside the same namespace CAN access private members of other classes defined in the same namespace?
Nope. I'm saying that if you use the
internal
modifier instead of theprivate
modified for class members, classes in the same assembly (I said namespace in my earlier post, but should have said assembly) will be able to access thoseinternal
members.Ok, scared me for a second. I thought I was missing some fundamental understanding of C#. I just realized after reading through my code, that by simply writing three more public methods, I can transfer the dealer logic to the table logic - and the logic is better placed in the table anyways. public BetAction[] GetPossibleActions(int Position); // Return an array of possible actions, given the game context, for the specified player. public Update(BetAction Action, int Position); // Update the game context, given the player action at the specified position. public int NextPlayerToAct(); // Return the position of the next player to act, given active players By simply calling GetPossibleActions(NextPlayerToAct()), you'll recieve an array of possible actions. If it's empty - the hand's over and the simulator (or whatever is controlling input to the table) will simply call StartNextRound() (which may call FinalizeHand(), if your on the last hand). If there are possible actions, (I have written public properties for the table which allow viewing, but not modifying table values), whatever selects the decision can view those properties and make a decision, then simply call the Update(SpecifiedAction, CurrentActingPlayer) which will update the game context and the player object. ... In other words, after thinking about this for awhile, I realized I don't need another class with private access. Thanks!
-
Ok, scared me for a second. I thought I was missing some fundamental understanding of C#. I just realized after reading through my code, that by simply writing three more public methods, I can transfer the dealer logic to the table logic - and the logic is better placed in the table anyways. public BetAction[] GetPossibleActions(int Position); // Return an array of possible actions, given the game context, for the specified player. public Update(BetAction Action, int Position); // Update the game context, given the player action at the specified position. public int NextPlayerToAct(); // Return the position of the next player to act, given active players By simply calling GetPossibleActions(NextPlayerToAct()), you'll recieve an array of possible actions. If it's empty - the hand's over and the simulator (or whatever is controlling input to the table) will simply call StartNextRound() (which may call FinalizeHand(), if your on the last hand). If there are possible actions, (I have written public properties for the table which allow viewing, but not modifying table values), whatever selects the decision can view those properties and make a decision, then simply call the Update(SpecifiedAction, CurrentActingPlayer) which will update the game context and the player object. ... In other words, after thinking about this for awhile, I realized I don't need another class with private access. Thanks!
I probably don't know enough about your application to advise you, but I won't let that stop me. :)
budidharma wrote:
public BetAction[] GetPossibleActions(int Position); // Return an array of possible actions, given the game context, for the specified player.
Do you have a Player class? Would that be a good idea, do you think? Also, who decides what the next BetAction will be? Maybe the logic for deciding should be in the Player class? If the logic varies, maybe have an IPlayer interface that can be implemented with various player strategy classes. Here's what the code might look like:
public interface IPlayer
{
bool Bet();event BetEventArgs BetPlaced;
}
Then somewhere else in your application:
PlayerCollection players = new PlayerCollection();
players.Add(new ConservativePlayer("Harry"));
players.Add(new AggressivePlayer("Joe"));
players.Add(new ModeratePlayer("Sue"));// ...
foreach(Player p in players)
{
if(!p.Bet())
{
break;
}
}The break looks ugly, and I'm sure there are cleaner ways of doing it. In part my suggestion is just guessing at a solution, but what I'm trying to get it is that maybe you should consider delegating some of the responsibilities of the table class to other classes. By putting everything in the table class, you may wind up with a monolithic class (a "God") class that does everything. This isn't considered good design in many circles. Just a thought, and feel free to ignore it. :)