Reputation: 11
writing a C# Program that prompts the user for the said details and displays them on the console.
Create the classes, along with the specified members as mentioned below.
question:
The code for the following question is not running. Can I please get some help. error is coming error CS0122: `Game.game_name' is inaccessible due to its protection level.
My code:
using System;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Enter a game");
string game_name = Console.ReadLine();
Console.WriteLine("Enter the maximum number of players");
int max_players = Convert.ToInt32(Console.ReadLine());
Game game = new Game();
game.GameName = game_name;
game.MaxNumPlayers = max_players;
Console.WriteLine("Enter a game that has time limit");
game_name = Console.ReadLine();
Console.WriteLine("Enter the maximum number of players");
max_players = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter time limit in minutes");
int time_limit = Convert.ToInt32(Console.ReadLine());
GameWithTimeLimit time_game = new GameWithTimeLimit();
time_game.GameName = game_name;
time_game.MaxNumPlayers = max_players;
time_game.TimeLimit = time_limit;
Console.WriteLine(game);
Console.WriteLine(time_game);
}
}
class Game
{
string game_name;
int max_players;
public string GameName
{
set
{
this.game_name = value;
}
}
public int MaxNumPlayers
{
set
{
this.max_players = value;
}
}
public override string ToString()
{
return "Maximum number of players for " + game_name + " is " + max_players;
}
}
class GameWithTimeLimit : Game
{
int time_limit;
public int TimeLimit
{
set
{
this.time_limit = value;
}
}
public override string ToString()
{
Console.WriteLine(base.ToString());
return "Time Limit for " + base.game_name + " is " + this.time_limit + " minutes";
}
}
Upvotes: 0
Views: 406
Reputation: 218828
I suspect you're getting the error here:
public override string ToString()
{
Console.WriteLine(base.ToString());
return "Time Limit for " + base.game_name + " is " + this.time_limit + " minutes";
}
This is in the GameWithTimeLimit
class, which inherits from the Game
class. Child classes can use fields on parent classes, but those fields need to be at least protected
in access level. The default when not specified is private
, which is what you have:
string game_name;
If this field is intended to be used by inheriting classes, you can make it protected:
protected string game_name;
Ideally, if something is meant to be used outside of the class (even by child classes), it should be a property. So instead I'd suggest something like this:
protected string GameName { get; set; }
There are further options you can explore, such as fields which are privately writable but publicly (or protectedly) readable, etc.
For any given member exposed by a class, be it a property/method/constructor/etc., it's important to ask yourself what protection level is needed. The "just make everything public so you don't have these problems" approach leads to its own problems. If something should be private, make it private. If it should be protected, make it protected. And so on. The decision is based on the externally-visible interface you want that class to expose.
Then, if you encounter a situation where you run into this error, you examine whether the protection level was wrong (the class' exposed interface needs to change) or whether the sitation itself is mistaken (the class is correct, the logic you've written needs to change). Either one can be equally likely.
Upvotes: 0
Reputation: 11080
In C#, when no access modifier is given to a class member it is defaulted to private. See the docs for a description of access modifiers and their defaults.
A private
member cannot be accessed from subclasses. This is why, in your GameWithTimeLimit
class, your attempt to access base.game_name
throws an error: game_name
is a private member and thus cannot be accessed from the subclass GameWithTimeLimit
.
If you want to hide the GameName from outside callers but use it in subclasses, you ought to use the protected
access modifier. But since you already have a public setter on your GameName
property, it would make sense to just add a public getter too:
public string GameName
{
get
{
return this.game_name;
}
set
{
this.game_name = value;
}
}
Then you can use it in your subclasses and other classes:
public override string ToString()
{
Console.WriteLine(base.ToString());
return "Time Limit for " + this.GameName + " is " + this.time_limit + " minutes";
}
Upvotes: 1
Reputation: 3732
The default protection level for items inside a class is private, so game_name
is a private field and can't be accessed by game.game_name
Create a public property
public string Name {get; set;}
Upvotes: 0