I am trying to make a database of weapons and have multiple attributes assigned to each weapon, such as name, attack value, buy value, sell value, etc.
namespace Testing
{
public class Weapon
{
public string name;
//other attributes would go here too
}
class Program
{
static void WeaponBuilder()
{
Weapon bSword = new Weapon();
bSword.name = "Bronze Sword";
//many other weapons would be built here
Console.WriteLine(bSword.name); //works fine
}
static void Main(string[] args)
{
WeaponBuilder();
Console.WriteLine(bSword.name); //error: bSword does not exist in the current context
WeaponShop();
Console.ReadLine();
}
static void WeaponShop()
{
Console.WriteLine("Buy " + bSword.name + "?"); //error: bSword does not exist in the current context
}
}
}
I need to be able to access the weapon's data outside of where it was constructed. Any help is appreciated. I know this is a noob question and I apologize.
You can put the data at the class level instead of an ephemeral local scoped variable:
class Program
{
static public Weapon bSword { get; } = new Weapon();
static void InitializeWeapon()
{
BSword.name = "Bronze Sword";
Console.WriteLine(bSword.name); //works fine
}
static void Main(string[] args)
{
InitializeWeapon();
Console.WriteLine(BSword.name);
WeaponShop();
Console.ReadLine();
}
...
}
Therefore it will be accessible inside the class and from outside in read-only mode here, as a composite.
It seems you want to manage several weapons, so you can for example use a List:
public class Weapon
{
public string Name { get; set; }
}
class Program
{
static public List<Weapon> Weapons { get; } = new List<Weapon>();
static void InitializeWeapons()
{
Weapons.Add(new Weapon { Name = "Bronze Sword" });
Weapons.Add(new Weapon { Name = "Silver Sword" });
foreach ( var weapon in Weapons )
Console.WriteLine(weapon.Name);
}
static void Main(string[] args)
{
InitializeWeapons();
ShopWeapon();
Console.ReadLine();
}
static void ShopWeapon()
{
foreach ( var weapon in Weapons )
{
Console.WriteLine($"Buy {weapon.Name}?");
// ...
}
}
}
What Are OOP Concepts?
What is abstraction in C#?
How to choose between public, private and protected access modifier?
What is polymorphism?
What is the difference between an interface and a class?
A basic structure for your classes can be something like:
// abstract means you cannot directly create a Weapon.
// Is is intended to be a base for concrete weapons
public abstract class Weapon
{
public abstract string Name { get; set; }
}
// A sword is a concrete weapon
// The base class "Weapon" forces it to have a name
public class Sword : Weapon
{
public override string Name { get; set; } = "sword";
}
// our weaponshop with a list of available weapons
public class WeaponShop
{
public List<Weapon> Weapons { get; } = new List<Weapon>();
// Let's add a sword to our weapon list when we are created
public WeaponShop()
{
Weapons.Add(new Sword());
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
WeaponShop myWeaponShop = new WeaponShop();
Console.WriteLine("The first sword is: " + myWeaponShop.Weapons.OfType<Sword>().FirstOrDefault().Name);
}
}
Create your class library on another file, (a good name would be weapon models), Make sure your class is set to static public (you pretty much set your data to static most the time, and public so it is accessible). Now in your Main file declare it on the top with a using statement or start typing the class you want to initiate and press Ctrl period. Then select add a using statement. This will automatically select your library, then you can use it! Also another shortcut, if you type the letters prop then tab twice, it will create a property for your class. Just be sure to initialize it! Also this was done using Visual Studio, some of the shortcuts might not work on VS code.
Related
I'm having troubles thinking of the design for my assignment.
for the assignment I would have 2 inheritance hierarchies and I would need to mimic multiple inheritance functionalities and the cross product so robotDog, robotBigDog, robotSmallDog, attackRobotDog, etc... it seems just doing multiple inheritance would end up being 9 different class files which is probably not the best approach.
for instance:
public class dog{
public virtual void bark{ Console.WriteLine("woof")};
}
public class bigDog : dog{
public override void bark{ Console.WriteLine("WOOF")};
}
public class smallDog : dog{
public override void bark{ Console.WriteLine("arf arf")};
}
public class robot{
public virtual void action{ Console.WriteLine("moves")}
}
public class attackRobot : robot{
public virtual void action{ Console.WriteLine("attacks")}
}
public class serviceRobot : robot{
public virtual void action{ Console.WriteLine("serves")}
}
I was instead thinking of doing a double composition of one class containing a dog and a robot because smallDog and bigDog can stand in for dog and attackRobot and serviceRobot can stand in for robot.
public class robotDog{
dog myDog;
robot myRobot;
public robotDog(dog typeDog, robot typeRobot){
myDog = typeDog;
myRobot = typeRobot;
}
.
. various functionality
.
}
is it a practical design to use double composition and also have a constructor that ask for a dog and robot? Or is there a different way to think/approach this?
You can not have multiple inheritance in C#, but you can have multiple interfaces.
You can use interfaces to define what a dog and a robot look like, create some different flavours of dog and robot, then combined them into a RobotDog class that has some defaults that can be overridden, i.e.
using System;
namespace ConsoleApp1
{
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
public class dog : IDog
{
public virtual void bark() { Console.WriteLine("woof"); }
}
public class bigDog : dog
{
public override void bark() { Console.WriteLine("WOOF"); }
}
public class smallDog : dog
{
public override void bark() { Console.WriteLine("arf arf"); }
}
public class robot : IRobot
{
public virtual void action() { Console.WriteLine("buzz, click"); }
}
public class attackRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public class serviceRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public interface IRobotDog : IDog, IRobot
{
IDog dog { get; set; }
IRobot robot { get; set; }
}
public class RobotDog : IRobotDog
{
public IDog dog { get; set; }
public IRobot robot { get; set; }
public RobotDog()
{
dog = new dog();
robot = new robot();
}
public RobotDog(IDog dogType)
{
dog = dogType;
robot = new robot();
}
public RobotDog(IRobot robotType)
{
dog = new dog();
robot = robotType;
}
public RobotDog(IDog dogType, IRobot robotType)
{
dog = dogType;
robot = robotType;
}
public void bark() { dog.bark(); }
public void action() { robot.action(); }
}
class Program
{
static void Main(string[] args)
{
RobotDog robotDog = new RobotDog();
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog(), new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog();
robotDog.dog = new bigDog();
robotDog.bark();
robotDog.action();
}
}
}
I would like to expand just a bit from what Xavier has offered. An interface is nothing more than a "contract". In its simplest form, any class that inherits an interface MUST declare the functions / methods / properties within it. So this way, any other object attempting to rely on its defined exposed components knows that it can, and they wont be missing. Now, you as the developer can implement that however you want and even have an empty function, provided the function actually exists but otherwise does nothing.
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
First, just simple dog or robot. Notice each implements their respective "REQUIRED" methods from the interface.
public class Dog : IDog
{
public void bark()
{
Console.WriteLine("Woof");
}
}
public class Robot : IRobot
{
public void action()
{
Console.Write("Activate jet pack, fly");
}
}
Notice below, the robotic dog never has an actual Dog or Robot class of its own. However, it DOES implement both individual requirements of each interface respectively into one major class of both.
public class RoboticDog : IDog, IRobot
{
public void bark()
{
Console.WriteLine("Woof -beep- woof");
}
public void action()
{
Console.Write("Activate jet pack, flying with fur");
}
}
Now, lets see how they operate individually.
static void Main(string[] args)
{
object testDog = new Dog();
object testRobot = new Robot();
object testBoth = new RoboticDog();
WhatCanIDo(testDog);
WhatCanIDo(testRobot);
WhatCanIDo(testBoth);
}
public void WhatCanIDo( object theThing )
{
// Here I am checking if the object is of a class type
// the inherits from IDog. If so, I can type-cast it as such
// and then call its "bark()" method as required to exist from interface.
if (theThing is IDog)
((IDog)theThing).bark();
// likewise if the object has interface of an IRobot
if (theThing is IRobot)
((IRobot)theThing).action();
}
I created a small console application for you with some small tips on how to catch when you need an interface over a base class, or vice-versa.
using System;
namespace ConsoleApp6
{
class Program
{
interface IWalkable
{
void Walk(int xAxis, int yAxis);
}
class Robot : IWalkable
{
public int RobotId { get; set; }
public Robot(int robotId)
{
RobotId = robotId;
Console.Write("Robot created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking beep boop");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
}
class BadRobot : Robot
{
public BadRobot(int robotId) : base(robotId)
{
}
}
class Dog : IWalkable
{
public Dog()
{
Console.Write("Dog created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking, roof roof");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
public virtual void Breath()
{
Console.WriteLine("I breath normal");
}
}
class BadDog : Dog
{
public override void Breath()
{
Console.WriteLine("I breath normal");
Console.WriteLine("But then I bark, because im bad");
}
//I can't "extend" an interface
//but I can extend a virtual method from the base class
}
static void Main(string[] args)
{
//three tips over inheritance
//1. If you want to abstract some *behavior*, you probably want an interface:
//for example here, both dogs and robots can walk. They are going to do that
//on their own way, so each need their own proper implementation,
//but the actions is the same thus, the interface
// An interface is meant to group objects over shared functionality
//so for example I can later do something like this
var dog = new Dog();
var badDog = new BadDog();
var badRobot = new BadRobot(1);
// these function doesn't care if its a dog or a robot
void WalkOverThere(IWalkable walkable)
{
//some other code...
walkable.Walk(5, 10);
}
//The key here is that the object pass over parameter implements the IWalk interface
WalkOverThere(badDog);
WalkOverThere(badRobot);
//Please notice that for each class that inherits "IWalkable"
//There will be a new implementation, so in this case, if
//all the robots inherit from the class robot, all will walk the same way
//In that, I cannot extend, or modify how that method is performed in the base
//class from the child class
//2. Now, the case is different when we talk about some functionality that could change
//for any child implementation of the base class. Think about the breath functionality
//A robot can't breathe, but a dog does. And given that every dog breaths differently
//it makes sense to create and virtual method, that means that I can reconfigure how
//the breath method behaves. For example:
dog.Breath();
badDog.Breath();
//3. Another thing that is useful to take into account is that
//whenever I can't create a given object without some piece of information,
//it makes sense to create the necessity of that data in the constructor.
//take for example in this code that I cannot create a robot without a valid int robotId
//This practice enforces me to create a robot like:
//var robot = new Robot(100); where 100 is the id
//var robot = new Robot(); the compile would not allow that
}
}
}
Any thoughts on why altitude is not 5 at the end of this program?
So I have a Penguin class deriving from Birds, and in Birds class I have a check on whether the birds is flightless, and based on that I reset the given altitude to 0 or keep the provided altitude.
Supposing penguins can fly (isFlightless=false), Penguin.ArrangeBirdInPatterns(p); should trigger the ArrangeBirdInTheSky, which it does, and then the altitude should be the one I provided (=5), not zero.
My VS crashed and I'm using online fiddlers, hard to debug.
using System;
public class Bird {
public double altitude;
public bool isFlightless;
public virtual void setLocation(double longitude, double latitude) {
}
public virtual void setAltitude(double altitude) {
this.altitude = altitude;
}
public void ArrangeBirdOnGround()
{
setAltitude(0);
}
public void ArrangeBirdInTheSky()
{
setAltitude(altitude);
}
public static void ArrangeBirdInPatterns(Bird b)
{
if(b.isFlightless)
{
b.ArrangeBirdOnGround();
}
else
{
b.ArrangeBirdInTheSky();
}
}
};
public class Penguin : Bird
{
public override void setAltitude(double altitude) {
}
}
public class Program
{
public static void Main()
{
Bird p = new Penguin();
p.setAltitude(5);
p.isFlightless = false;
Penguin.ArrangeBirdInPatterns(p);
Console.WriteLine(p.altitude); //// returns 0. why not 5
}
}
Also, why can't I call it like: ArrangeBirdInPatterns(p); if I remove static from the ArrangeBirdInPatterns definition?
You're calling Penguin's setAltitude, which does nothing.
The type of p is Bird, but the type of the value contained there is Penguin, which overrides Bird.setAltitude, so that's what gets called.
You can look into the differences between virtual, override, and new keywords for more info on the different ways to subclass.
I am working on a C# game that will have predefined levels. I am trying to have a class that will hold the predefined data of all of the levels. Here's what I'm trying to do:
public static GameLevel startLevel = new Level() {
startLevel.Actions.Add(action);
startLevel.Actions.Add(action);
}
And so on. However, it seems that C# does not want me to initialize this way. How can I achieve my desired effect without throwing it into a massive constructor?
How do you think if we change the static variable as below:
private static GameLevel _startLevel;
public static GameLevel StartLevel
{
get
{
if(_startLevel == null)
{
_startLevel = new Level();
_startLevel.Action.Add(action1);
_startLevel.Action.Add(action2);
}
return _startLevel;
}
}
Since you have predefined levels, I suggest a little different approach.
Create a Level base class, and a class for each Level. The constructor for each level class can set up the Actions and any other things the game needs to know how to display itself.
using System;
public class Program
{
public static void Main()
{
new GameState(new Level1());
Console.WriteLine("Current level is " + GameState.CurrentLevel.Name);
Console.WriteLine("User leveled up");
GameState.CurrentLevel = new Level2();
Console.WriteLine("Current level is " + GameState.CurrentLevel.Name);
}
}
public class Level
{
public string Name;
// public static IEnumerable<Action> Actions { get; set; }
}
public class Level1 : Level
{
public Level1()
{
// level 1 init
Name = "1";
// Actions = new List<Action> { ... }
}
}
public class Level2 : Level
{
public Level2()
{
// level 2 init
Name = "2";
}
}
public class GameState
{
public static Level CurrentLevel { get; set; }
public GameState(Level startLevel)
{
CurrentLevel = startLevel;
}
}
Working copy: https://dotnetfiddle.net/qMxUbw
"...C# does not want me to initialize this way..."
You can init this way. You simply don't have the right syntax. This should work
public static Level startLevel = new Level()
{
Actions = new List<Action>()
{
new Action() {...},
new Action() {...}
},
OtherProprty = "Other"
};
NOTE: this has to be done under class scope
"Massive constructor" - you usually don't init static members in constructor unless this is static constructor. Sounds like you need to use Singleton pattern for this piece. Then again, you call all the needed code in constructor, "massive" or not. Break it into methods.
I'm testing this program for inheritance I have 3 classes ( animal,emu,kangaroo)
and main class.
emu and kangaroo derived from Animal class.
when I try to run the program getting error Emu.Bird(), Kangaroo.Mamel() is not suitable method found to overide. I'm doing it by a random tutorial and not sure about the "override" and what exactly it does.
static void Main(string[] args)
{
Emu e = new Emu("Emu","Brown", "is a bird");
Console.WriteLine();
Kangaroo k = new Kangaroo("Kangaroo","Dark Brown", "Is a mamel" );
Console.ReadLine();
}
Animal Class
class Animal
{
public string name;
public string colour;
public Animal(string MyName,string MyColour)
{
name = MyName;
colour = MyColour;
}
public virtual void Show()
{
Console.WriteLine("Name: "+ name);
Console.WriteLine("Colour: "+ colour);
}
}
Emu Class
class Emu:Animal
{
public string bird;
public Emu(string name,string colour, string eBird) : base(MyName,MyColour)
{
bird = eBird;
}
public override void Bird()
{
base.Show();
Console.WriteLine(bird);
}
}
Kangaroo Class
class Kangaroo:Animal
{
public string mamel;
public Kangaroo(string name,string colour, string Mamel) : base(MyName,MyColour)
{
mamel = Mamel;
}
public override void Mamel()
{
base.Show();
Console.WriteLine("Is a bird or Mamel ? " + mamel);
}
}
The word override in coding means to replace the implementation of an existing method, i.e overriding the previous method.
So here in your case, the class that you are inheriting from doesn't have mamel or bird method.
Don't just read random articles..go by series of topics. Refer a book or some tutorial series.
Check if you can pdf version of CLR via C#
or you can also refer our ongoing tutorial series at CheezyCode
I want to know how to pass down instances of objects without knowing the Type that they are. I'd like to know this because if I have a 100 animal types, then I don't want to have a 100 if statements or a switch. I have provided a snippet, which is an example of what I want to basically achieve. Right now it obviously doesn't work where I put the comments at.
using System.IO;
using System;
using System.Collections.Generic;
class Program
{
Dictionary<string, dynamic> myAnimals = new Dictionary<string, dynamic>();
Program(){
myAnimals.Add("Maggie", new Dog("Maggie"));
myAnimals["Maggie"].bark();
myAnimals.Add("Whiskers", new Cat("Whiskers"));
myAnimals["Whiskers"].meow();
animalClinic clinic = new animalClinic();
clinic.cureAnimal(myAnimals["Whiskers"]);
}
static void Main()
{
new Program();
}
}
class Dog{
string name;
public Dog(string n){
name = n;
}
public void bark(){
Console.WriteLine("\"Woof Woof\" - " + name);
}
}
class Cat{
string name;
public Cat(string n){
name = n;
}
public void meow(){
Console.WriteLine("\"Meow Meow\" - " + name);
}
}
class animalClinic(){
public void cureAnimal(object animal){ //This is where I need some help.
if(animal.name == "Maggie"){ //I know I can use 'animal.GetType() == ...' That isn't the point.
Console.WriteLine("We heal fine dogs!"); //The point is to access various methods within the object.
}else{//I know it kind of beats the point of Type-Safety, but this is only an example and another way to do this is perfectly fine with me.
Console.WriteLine("Eww a cat!")
}
}
}
If anyone knows an alternative solution to this, then please go ahead and share!
Thanks.
EDIT: I think you'll also need to reference the animal instead of just passing it down.
This is what polymorphism is for:
public interface IAnimal
{
string name {get;set;}
void speak();
void cure();
}
public class Dog : IAnimal
{
public Dog (string n)
{
name = n;
}
public string name {get;set;}
public void bark()
{
Console.WriteLine("\"Woof Woof\" - " + name);
}
public void speak() { bark(); }
public void cure()
{
Console.WriteLine("We heal fine dogs!");
}
}
public class Cat : IAnimal
{
public Cat(string n)
{
name = n;
}
public string name {get;set;}
public void meow()
{
Console.WriteLine("\"Meow Meow\" - " + name);
}
public void speak() { meow(); }
public void cure()
{
Console.WriteLine("Eww a cat!");
}
}
class Program
{
static Dictionary<string, IAnimal> myAnimals = new Dictionary<string, IAnimal>();
static void Main()
{
myAnimals.Add("Maggie", new Dog("Maggie"));
myAnimals["Maggie"].speak();
myAnimals.Add("Whiskers", new Cat("Whiskers"));
myAnimals["Whiskers"].speak();
animalClinic clinic = new animalClinic();
clinic.cureAnimal(myAnimals["Whiskers"]);
}
}
public class animalClinic
{
public void cureAnimal(IAnimal animal)
{
animal.cure();
}
}
Create an interface (contains definitions for a group of related functionalities that a class or a struct can implement) called IAnimal which contains a Description property which returns "We heal fine dogs!" for your Dog class etc. Each of your concrete animal classes implement this interface meaning you can just call the Description property in your cureAnimal method.
Use polymorphism.
public abstract class Animal
{
public string Name { get; set; }
public abstract void Cure();
}
public class AnimalClinic
{
public void CureAnimal(Animal animal)
{
animal.Cure();
}
}
public class Dog : Animal
{
public override void Cure()
{
Console.WriteLine("We heal fine dogs!");
}
}
If you want to define the Cure logic inside of the AnimalClinic class like you do now, you might have to perform conditional execution of some sort.
This conditional execution does not have to be as unwieldy as a massive if statement or even a switch. You can research alterantive solutions to if statements here on SO. In fact, Joel Coehoorn has supplied one.
I believe the best option here is to use the strategy design pattern. Perfectly explained here http://www.dofactory.com/net/strategy-design-pattern
An example for your case is provided by ByteBlast and Joel Coehoorn's answers