I'm building a simple class that allows me to calculate the dimensions of the room for a class and I'm having trouble getting the code to work. When I run it these are the errors I am receiving.
/p1/room.cs(1,7): error CS0116: A namespace cannot directly contain members such as fields or methods
/p1/room.cs(48,19): warning CS0108: 'Room.GetType()' hides inherited member 'object.GetType()'. Use the new keyword if hiding was intended.
/p1/room.cs(1,1): error CS0246: The type or namespace name 'Using' could not be found (are you missing a using directive or an assembly reference?)
I did some research and found that it seems that most of the time the two above errors refer to either unmatched brackets, but after searching through my room.cs file, I was unable to find any. In comparing the headers to my files to other classes I've found I can't find any differences.
Here is my room.cs file
Using System;
namespace p1
{
public class Room
{
private string type;
private double length;
private double width;
private double height;
public Room()
{
type = "Default";
length = 0.0;
width = 0.0;
height = 0.0;
}
public Room(string t, double l, double w, double h)
{
type = t;
length = l;
width = w;
height = h;
}
public void SetType(string t)
{
type = t;
}
public void SetLength(double l)
{
length = l;
}
public void SetWidth(double w)
{
width = w;
}
public void SetHeight(double h)
{
height = h;
}
public string GetType()
{
return type;
}
public double GetLength()
{
return length;
}
public double GetWidth()
{
return width;
}
public double GetHeight()
{
return height;
}
public double GetArea()
{
return length*width;
}
public double GetVolume()
{
return length*width*height;
}
public void Display()
{
Console.WriteLine("Room Type: " + this.GetType());
Console.WriteLine("Room Length: " + this.GetLength());
Console.WriteLine("Room Width: " + this.GetWidth());
Console.WriteLine("Room Height: " + this.GetHeight());
Console.WriteLine("Room Area: " + this.GetArea().ToString("F 2") + " sq ft " );
Console.WriteLine("Room Volume: " + this.GetVolume().ToString("F 2") + " cu ft ");
}
}
}
I can also post the program.cs file if needed, but this was getting quite long and I didn't want it to be unreadable.
Correct syntax to use NameSpace should be using not Using
Replace Using System; with using System;
Use
public new string GetType()
{
return type;
}
in place of to get rid of warning "Use new keyword is hiding was intented"
public string GetType()
{
return type;
}
In addition to what vivek nuna already said, you should get used to C#'s concept of properties. This will make your code less verbose and avoids the specific problem of hiding GetType():
public class Room
{
public string Type { get; set; } = "Default"; // with C#6 property initialization
public double Length { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public Room() {} // no code here, Type is initalized, double is 0 by default
public Room(string t, double l, double w, double h)
{
Type = t;
Length = l;
Width = w;
Height = h;
}
public double GetArea()
{
return Length * Width;
}
public double GetVolume()
{
return Length * Width * Height;
}
public void Display()
{
Console.WriteLine("Room Type: " + Type);
Console.WriteLine("Room Length: " + Length);
Console.WriteLine("Room Width: " + Width);
Console.WriteLine("Room Height: " + Height);
Console.WriteLine("Room Area: " + GetArea().ToString("F 2") + " sq ft " );
Console.WriteLine("Room Volume: " + GetVolume().ToString("F 2") + " cu ft ");
}
}
From outside you can now simply access the properties:
Room r = new Room();
r.Height = 12;
Console.WriteLine(r.Height);
The compiler does all the work you did yourself in your code. It creates backing fields for each property and the getter and setter methods. You don't have to do this and can concentrate on the real work.
Related
I want to create a Compound Interest Calculator in C# using two classes in different namespaces but can't for the life of me figure out why I keep getting errors.
PSA I am a beginner, I know this code probably looks awful, but please be kind.
Here is CompoundTest.cs
namespace CompoundTest
{
class Program
{
static void Main(string[] args)
{
CompoundClass newprogram = new CompoundClass();
Console.Write("\nPlease enter the initial balance for your account: ");
double balance = Convert.ToDouble(Console.ReadLine());
Console.Write("\nPlease enter the annual interest rate: ");
double interestRate = Convert.ToDouble(Console.ReadLine()) / 100;
Console.Write("\nHow many years will you acrue interest? ");
double annualAmount = Convert.ToDouble(Console.ReadLine());
Console.WriteLine($"Your balance after {annualAmount} years is {accountBalance:C}");
Console.ReadLine();
}
}
}
And here is Compound.cs
using System;
namespace Compound
{
public class CompoundClass
{
private double balance;
public int value { get; private set; }
public CompoundClass()
{
Balance = value;
}
public double Balance
{
get
{
return balance;
}
private set
{
if (value > 0)
{
balance = value;
}
}
}
public void Rate(double interestRate)
{
interestRate = value / 100;
}
public void Years(double annualAmount)
{
annualAmount = value * 12;
}
public void addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
accountBalance = balance * Math.Pow(1 + interestRate / annualAmount, annualAmount * i);
}
}
}
}
I get the error:
CS0103 C# The name '..' does not exist in the current context - in the public void addMethod(double accountBalance) method
You are not storing any data on the CompoundClass, the method
public void Rate(double interestRate)
{
interestRate = value / 100;
}
only operates on the input parameter interestrate inside the functions scope, after that the result of the calculation is lost
If you want to reuse a variable on the entire lifetime of the CompoundClass, then define it as a member variable like:
private double _interestRate
and change your function to
public void Rate()
{
_interestRate = value / 100;
}
and for the annualAmount as well
private double _annualAmount;
public void Years()
{
_annualAmount = value * 12;
}
and your calculation to
public double addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
accountBalance = balance * Math.Pow(1 + _interestRate / _annualAmount, _annualAmount * i);
}
return accountBalance;
}
There is more then one thing wrong with this code. And I am honestly not sure if I even got anything close to your problem yet.
using System;
namespace Compound
{
public class CompoundClass
{
private double balance;
public int value { get; private set; }
public CompoundClass()
{
//Balance with a big B is nowhere in context
Balance = value;
}
public double Balance
{
get
{
return balance;
}
private set
{
if (value > 0)
{
balance = value;
}
}
}
//As remarked by somebody else, this function does nothing. Without return or out parameter, interest rate will stay at nothing.
public void Rate(double interestRate)
{
interestRate = value / 100;
}
//The naming of this variable is bad. Did you mean "Amoung of Months"?
//Also as someone else pointed out, you do not return or otherwise persist this value
public void Years(double annualAmount)
{
annualAmount = value * 12;
}
//Method does not return anything.
//accountBalance is a local value and will not persist
public void addMethod(double accountBalance)
{
for (int i = 1; i < annualAmount + 1; i++)
{
//Avoid putting that much stuff into 1 line. It really messes with your ability to debug
//1-2 operations + 1 assignment to a temporary variable per line
//Anything more and you will have serious issues debugging this
accountBalance = balance * Math.Pow(1 + interestRate / annualAmount, annualAmount * i);
}
}
}
}
Generally the variables this works with should be either purely parameters (wich means it should be a static class with static functions) or mostly class variables. You have both things mixed all over the place.
I am writing a class called Television that does a few simple controls, but I am running into an issue with my ToString method. "'Television.ToString()': not all code paths return a value". How would I go about returning either message? Any help is appreciated greatly, thank you.
class Television
{
private string manufacturer;
private int screenSize;
private bool powerOn = false; // the power is off by default
private int channel = 2; // channel is default set to 2
private int volume = 20; // volume default set to 20
public Television (string manu, int size) // The purpose of this constructor is to initialize the manufacturer and screen size fields.
{
manufacturer = manu;
screenSize = size;
}
public int GetVolume() // accessor method that returns volume
{
return volume;
}
public int GetChannel() // accessor method that returns channel
{
return channel;
}
public string GetManufacturer() // accessor method that returns manufacturer
{
return manufacturer;
}
public int GetScreenSize() // accessor method that returns screen sizes
{
return screenSize;
}
public void SetChannel(int userChannel) // mutator method that changes the channel
{
Console.WriteLine("What channel would you like to watch?: ");
userChannel = int.Parse(Console.ReadLine());
userChannel = channel;
}
public void power() // mutator method that turns the power on/off
{
powerOn = !powerOn;
}
public void IncreaseVolume() // mutator method that increases volume by 1
{
volume = volume + 1;
}
public void DecreaseVolume() // mutator method that decreases volume by 1
{
volume = volume - 1;
}
**public string ToString()
{
if (powerOn == false) {
Console.WriteLine("A " + screenSize + " inch " + manufacturer + " has been turned off.");
}
else if (powerOn == true)
{
Console.WriteLine("A " + screenSize + " inch " + manufacturer + " has been turned on.");
}**
}
}
}
ToString should override the base method to respect the polymorphism design and it must return a string but you return nothing:
public override string ToString()
{
string str = "A " + screenSize + " inch " + manufacturer + " has been turned ";
return str + ( powerOn ? "on." : "off." );
}
Or:
public override string ToString()
{
return $"A {screenSize} inch {manufacturer} is turned {(powerOn ? "on" : "off")}.";
}
Therefore you can use:
var television = new Television();
Console.WriteLine(television.ToString());
MessageBox.Show(television.ToString());
label.Text = television.ToString();
In Unity 3D, I am trying to build a Dictionary of PathNodes keyed by NodeCoordinates. I have overridden GetHashCode in NodeCoordinate and it should return a constant unique value. If I loop through the keys of the dictionary, the lookup works fine, but if I create a new NodeCoordinate with the coordinates of a PathNode that should exist, the lookup fails even though the hash codes are equal.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PathNode : MonoBehaviour {
public static Dictionary<NodeCoordinate, PathNode> pathNodes;
public PathNode left;
public PathNode right;
public PathNode forward;
public PathNode backward;
private NodeCoordinate coord;
void Awake()
{
if (PathNode.pathNodes == null)
{
PathNode.pathNodes = new Dictionary<NodeCoordinate, PathNode>();
}
NodeCoordinate coord = new NodeCoordinate(transform.position.x, transform.position.z);
this.coord = coord;
PathNode.pathNodes.Add(coord, this);
NodeCoordinate leftChord = new NodeCoordinate(coord.x - 1, coord.z);
NodeCoordinate rightChord = new NodeCoordinate(coord.x + 1, coord.z);
NodeCoordinate forwardChord = new NodeCoordinate(coord.x, coord.z + 1);
NodeCoordinate backwardChord = new NodeCoordinate(coord.x, coord.z - 1);
if (PathNode.pathNodes.ContainsKey(leftChord))
{
this.left = PathNode.pathNodes[leftChord];
this.left.right = this;
}
if (PathNode.pathNodes.ContainsKey(rightChord))
{
this.right = PathNode.pathNodes[rightChord];
this.right.left = this;
}
if (PathNode.pathNodes.ContainsKey(forwardChord))
{
this.forward = PathNode.pathNodes[forwardChord];
this.forward.backward = this;
}
if (PathNode.pathNodes.ContainsKey(backwardChord))
{
this.backward = PathNode.pathNodes[backwardChord];
this.backward.forward = this;
}
}
private static bool debug = true;
void Update()
{
if (debug)
{
foreach (NodeCoordinate coord in PathNode.pathNodes.Keys)
{
Debug.Log(coord + " : " + PathNode.pathNodes[coord] + " : " + coord.GetHashCode());
}
foreach (PathNode node in PathNode.pathNodes.Values)
{
NodeCoordinate leftChord = new NodeCoordinate(node.coord.x - 1, node.coord.z);
PathNode leftNode;
Debug.Log("Left: " + leftChord + " : " + PathNode.pathNodes.TryGetValue(leftChord, out leftNode) + " : " + leftChord.GetHashCode());
}
debug = false;
}
}
}
public class NodeCoordinate
{
public float x;
public float z;
public NodeCoordinate(float x, float z)
{
this.x = x;
this.z = z;
}
public bool Equals(NodeCoordinate coord)
{
return (this.x == coord.x && this.z == coord.z);
}
public override int GetHashCode()
{
return string.Format("{0}x{1}", this.x, this.z).GetHashCode();
}
public override string ToString()
{
return "Coordinate: " + this.x + " x " + this.z;
}
}
This is the output from my little debug:
debug log
As you can see, when looping through the keys, the lookups with hashcodes 2137067561 and 1824497336 work, but when I instantiate a new NodeCoordinate and try to look it up, it has the same hashcode but the lookup fails. Any idea why this is happening? Thanks.
The problem is that your NodeCoordinate class doesn't define equality in a way that the dictionary would use. You have a method like this:
public bool Equals(NodeCoordinate coord)
... but you neither override IEquatable<NodeCoordinate> nor do you override Equals(object).
Personally I'd suggest doing both - and implementing a simpler hash code that doesn't require string formatting:
public sealed class NodeCoordinate : IEquatable<NodeCoordinate>
{
public float X { get; }
public float Z { get; }
public NodeCoordinate(float x, float z)
{
X = x;
Z = z;
}
public override Equals(object other) => Equals(other as NodeCoordinate);
public bool Equals(NodeCoordinate coord) =>
coord != null && this.X == coord.X && this.Z == coord.Z;
public override int GetHashCode()
{
int hash = 23;
hash = hash * 31 + X;
hash = hash * 31 + Z;
return hash;
}
public override string ToString() => $"Coodinate: {X} x {Z}";
}
(Note that I've also made it immutable and used properties instead of public fields. I've used C# 6 syntax for simplicity, but it wouldn't be hard to translate to C# 5 if necessary.)
So for some reason, when I add a IEqualityComparer with the exact same logic, it works.
Changed the declaration of the dictionary to this:
if (PathNode.pathNodes == null)
{
PathNode.pathNodes = new Dictionary<NodeCoordinate, PathNode>(new NodeCoordinateComparer());
}
Added this:
public class NodeCoordinateComparer : IEqualityComparer<NodeCoordinate>
{
public bool Equals(NodeCoordinate a, NodeCoordinate b)
{
return (a.x == b.x && a.z == b.z);
}
public int GetHashCode(NodeCoordinate coord)
{
return string.Format("{0}x{1}", coord.x, coord.z).GetHashCode();
}
}
I have problems with the encapsulation, and I don't where the problem is. Why can the line be altered after it has been created? This tells me something is wrong in my "line-class" and needs to be encapsulated. Advise would be much appreciated.
When calling "pa.X = 4" and "startpos.Y = 7" this should not change the line for me, but it does. I expect that all the lines are unchanged when the program has finished.
Dotclass:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dot
{
class Dot
{
private int x;
private int y;
public Dot()
{
this.X = 0;
this.Y = 0;
}
public Dot(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X
{
get
{ return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
}
}
Lineclass:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dot
{
class Line
{
private Dot startdot;
private Dot enddot;
private double length;
public Line(Dot pa, Dot pb)
{
this.startdot = pa;
this.enddot = pb;
}
public double Size()
{
double a = (double)(enddot.X - startdot.X);
double b = (double)(enddot.Y - startdot.Y);
return length = Math.Sqrt(a * a + b * b);
}
public Dot Position()
{
return startdot;
}
}
}
Main:
using System;
namespace Dot
{
class Program
{
public static void Main()
{
Dot pa = new Dot();
Dot pb = new Dot(-10, -10);
Console.WriteLine("Dot pa, position = (" + pa.X + ", " + pa.Y + ")");
Console.WriteLine("Dot pb, position = (" + pb.X + ", " + pb.Y + ")");
Line line = new Line(pa, pb);
Print("Run 1 off line", line);
pa.X = 4;
Print("Run 2 off line", line);
Dot startpos = line.Position();
startpos.Y = 7;
Print("Run 3 off line", line);
}
private static void print(string text, Line line)
{
double length = line.Size();
Dot startPos = line.Position();
Console.WriteLine("\n" + text);
Console.WriteLine("Längd = {0 :f4} length", length);
Console.WriteLine("Position = ({0},{1})", startPos.X, startPos.Y);
Console.ReadLine();
}
}
}
Why can the line be altered after it has been created?
The reason is that class Dot is a reference type, and you want a value type, struct:
// please, notice "struct"
public struct Dot {
// you don't need separate fields, but properties
public int X {get; set;}
public int Y {get; set;}
public Dot(int x, int y) {
X = x;
Y = y;
}
}
....
EDIT: I suggest turning public Dot Position() into property as well:
class Line {
...
public Dot Position {
get {
return startdot;
}
set {
startdot = value;
}
}
}
and so you can "control the angles":
line.Position = new Dot(line.Position.X, 5);
Hey i just started by C# class 2 weeks ago so i am beginner programmer
and i am having trouble with my code. i have 2 classes, one of them is the test case that runs the program and the other has private variables. my variables color, NumOfWheels, StartingPoint, CurrentSpeed, and Mileage says property or indexer cannot be assigned to - it is read only when i try to build it. how do i fix this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Homework1
{
class Car
{
private string color;
private int numOfWheels;
private int startingPoint;
private int mileage;
private int currentSpeed;
public Car()
{
Color = "";
NumOfWheels = 4;
StartingPoint = 100000;
CurrentSpeed = 0;
Mileage = 0;
}
public Car(string color, int numOfWheels, int startingPoint, int currentSpeed, int mileage)
{
Color = color;
NumOfWheels = numOfWheels;
StartingPoint = startingPoint;
CurrentSpeed = currentSpeed;
Mileage = mileage;
}
public virtual void setcolor(string color)
{
this.color = color;
}
public virtual void setnumOfWheels(int numOfWheels)
{
this.numOfWheels = numOfWheels;
}
public virtual string Color
{
get
{
return color;
}
}
public virtual double NumOfWheels
{
get
{
return numOfWheels;
}
}
public virtual int StartingPoint
{
get
{
return startingPoint;
}
}
public virtual int CurrentSpeed
{
get
{
return currentSpeed;
}
}
public virtual int Mileage
{
get
{
return mileage;
}
}
public override string ToString()
{
return (" color " + color + " numOfWheels" + numOfWheels + "startingPoint " + startingPoint + "mileage" + mileage + "current speed" + currentSpeed);
}
}
}
********************************************************************************
/// this is the test case that runs the program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class CarTest
{
static void Main(string[] args)
{
Car myCar = new Car();
Console.WriteLine("*****************************");
Console.WriteLine("* *");
Console.WriteLine("* WELCOME TO CAR MANAGER *");
Console.WriteLine("* By <<my Name>> *");
Console.WriteLine("* *");
Console.WriteLine("*****************************");
Console.WriteLine("\nEnter the number of wheels of a car");
int numOfWheels = Console.Read();
myCar.setWheels(numOfWheels);
Console.WriteLine("Enter the color of the car");
String color = Console.ReadLine();
Console.WriteLine("Current mileage will be set to zero");
Console.WriteLine("The current starting point will be set to 100000");
Console.Write("The current status of your car \n{0:D} Wheels, \n{1}, \n{2:D} Miles and \nCAR POINT = {3:D}", myCar.getNumOfWheels,
myCar.getColor, myCar.getMileage, myCar.getStartingPoint);
Console.WriteLine("\nEnter the owner's name");
String name = Console.ReadLine();
Console.WriteLine("Enter the miles the car ran in this week");
int milesThisWeek = Console.ReadLine;
myCar.setMileage(Mileage);
Console.WriteLine("This car is owned by n{1}", name);
Console.WriteLine("===>The current status of your car:");
Console.WriteLine("Wheels: " + myCar.getWheels());
Console.WriteLine("Color: " + myCar.getColor());
Console.WriteLine("Current Mileage: " + myCar.getMileage());
Console.WriteLine("Starting Point: " + myCar.getStartingPoint());
Console.WriteLine("************ Thank you for using CAR MANAGER *************");
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine("Press ENTER to close console…….");
}
}
}
You're trying to set a property:
Color = "";
(among other places) But that property doesn't have a setter, only a getter:
public virtual string Color
{
get
{
return color;
}
}
In order to set the value of a property, it needs a setter:
public virtual string Color
{
get
{
return color;
}
set
{
color = value;
}
}
(repeat for your other properties as well)
It looks like you're trying to create Java-like setter methods:
public virtual void setcolor(string color)
{
this.color = color;
}
This works, and you can call those instead of trying to set the properties:
setColor("");
But it's not the expected convention in C#. The properties can manage the backing variables themselves. In fact, you can remove the backing variables entirely and use auto-implemented properties for simple values:
public virtual string Color { get; set; }
If you just need to hold a value, a simple property does that just fine. Methods are more for operations in code, not for getting/setting simple values. (Additionally, you wouldn't want to get into the habit of calling a lot of methods from a constructor. A constructor should really just build the state of the object and nothing else.)