here is my main method:
string input = Console.ReadLine(); // 2006 2000 false 1000 500 Windows
List<string> inputs = input.Split(" ").ToList();
Computer one = new Computer(int.Parse(inputs[0]), int.Parse(inputs[1]), bool.Parse(inputs[2]), double.Parse(inputs[3]), double.Parse(inputs[4]), inputs[5]);
one.Print(); // 2006, 2000, false, 1000, 500, Windows
input = Console.ReadLine(); //changeOperatingSystem
if (input == "changeOperatingSystem")
{
string newOperationSystem = Console.ReadLine(); //Linux
Computer two = new Computer(newOperationSystem);
}
one.Print(); //2006, 2000, false, 1000, 500, Linux
the "//" marks what the input and the output look like.
This is my Computer.cs:
private int years;
private int price;
private bool isNotebook;
private double hardDiskMemory;
private double freeMemory;
private string operationSystem;
private string newOperationSystem;
public Computer(int years, int price, bool isNotebook, double hardDiskMemory, double freeMemory, string operationSystem)
{
Years = years;
Price = price;
IsNotebook = isNotebook;
HardDiskMemory = hardDiskMemory;
FreeMemory = freeMemory;
OperationSystem = operationSystem;
}
public Computer(string newOperationSystem)
{
OperationSystem = newOperationSystem;
}
public int Years
{
get { return years; }
set
{
years = value;
}
}
public int Price
{
get { return price; }
set
{
price = value;
}
}
public bool IsNotebook
{
get { return isNotebook; }
set
{
isNotebook = value;
}
}
public double HardDiskMemory
{
get { return hardDiskMemory; }
set
{
hardDiskMemory = value;
}
}
public double FreeMemory
{
get { return freeMemory; }
set
{
freeMemory = value;
}
}
public string OperationSystem
{
get { return operationSystem; }
set
{
operationSystem = value;
}
}
public string NewOperationSystem
{
get { return NewOperationSystem; }
set
{
newOperationSystem = value;
}
}
public void Print()
{
Console.WriteLine($"{years}, {price}, {isNotebook}, {hardDiskMemory}, {FreeMemory}, {operationSystem}");
}
what I want this program to do is whenever the input submitted by the user is "changeOperationSystem" the program gives the user another input where they submit the new Operation system for the pc. Then with the constructor, the Computer.Cs receives the string newOperationSystem, which then should replace the value operationSystem as I tried to do in the constructor: OperationSystem = newOperationSystem, but it doesn't work. I am stil learning classes so don't go hard on me.
It seems to me you are trying to change one property of a class. All you have to do is use the property set method
one.OperationSystem = newOperationSystem;
and remove the property NewOperationSystem altogether.
Here is a bare bones skeleton code of instantiating a class with a constructor and then changing one of the properties
public class Foo
{
private int _a;
private string _b;
private readonly float _c;
public Foo(int a, string b, float c)
{
_a = a;
_b = b;
_c = c;
}
public int A { get => _a; set => _a = value; }
public string B { get => _b; set => _b = value; }
public float C => _c;
public override string ToString()
{
return $"{_a}, {_b}, {_c}";
}
}
class Program
{
static void Main(string[] args)
{
Foo one = new Foo(100, "Philip", 0.75f);
Console.WriteLine(one);
//100, Philip, 0.75
one.B = "Spencer";
Console.WriteLine(one);
//100, Spencer, 0.75
}
}
Another feature of the code above is that there is no need to create a .Print() method, if you can take advantage of the built-in .ToString() which gets called automatically during a Console.WriteLine() or any other operations that require a string input from my class.
Finally, I added a read-only property C to demonstrate that this design is possible. You will not be able to write one.C = 0.25f; since the property is read-only.
Related
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Week7_A
{
class Experiment
{
public string NAME { get; set; }
private int NUM { get; set; }
private string COLOR;
private double WEIGHT;
private double VOLUME;
private string[] colors = new string[6] {"Crimson", "Azure", " Taupe", "Mauve", "Vermillion", "Chartreuse"};
public bool error;
public Experiment(string Name, int Num, string Col, double Weight)
{
NAME = Name;
NUM = Num;
COLOR = color;
WEIGHT = weightt;
}
public string color
{
get { return COLOR; }
set
{
foreach(string i in colors)
{
if (value == i)
error = false;
break;
}
}
}
public double weightt
{
get { return WEIGHT; }
set { WEIGHT = value; }
}
}
}
There is serious conceptual confusion in coding. I edited the code you want to do below and developed a test application. I recommend reading this article to get a grasp of the classes. The test application produces the following output:
Name: John, Number: 15, Color: Chartreuse, Weight: 50.75
using System;
namespace Test
{
public class Experiment
{
// "STATIC VARIABLE": You must define "static" data that takes a constant value inside the class.
private static string[] colors = new string[6] {"Crimson", "Azure", " Taupe", "Mauve", "Vermillion", "Chartreuse"};
// "FIELDS": Fields are generally defined as "private" and are closed to external setting.
private string _name;
private int _number;
private string _color;
private double _weight;
private double _volume;
public bool _errorState;
// "CONSTRUCTOR": The constructor is used to initialize an object. It is not necessary to assign directly to fields without checking the value.
public Experiment(string name, int number, string color, double weight)
{
_name = name; // Not recommended use; the value is assigned to the field without checking it.
_number = number; // Not recommended use; the value is assigned to the field without checking it.
Color = color; // Recommended Usage; in the set method of the Property, the field is checked before assigning a value. However, there is a logic error in this usage.
Weight = weight; // Not recommended use; property's set method does not check before assigning the field.
}
// "PROPERTIES": The properties provide the interface for the "private" defined fields to be accessible.
public string Color
{
get { return _color; }
set
{
foreach(string i in colors){
if (value == i) {
_errorState = false;
} else {
_color = i;
}
}
}
}
public double Weight
{
get { return _weight; }
set { _weight = value; }
}
public string Name
{
get { return _name; }
}
public int Number
{
get { return _number; }
}
}
}
public class Program
{
public static void Main()
{
Test.Experiment experiment = new Test.Experiment("John", 15, "blue", 50.75);
Console.WriteLine("Name: {0}, Number: {1}, Color: {2}, Weight: {3}", experiment.Name, experiment.Number, experiment.Color, experiment.Weight);
}
}
I'm having trouble with a stack overflow exception but I can't tell what's causing the exception to be thrown. I'm using a class library that contains all the methods and objects I need and running it from a console application.
Any help would be greatly appreciated as this is part of an assignment that is due in a couple of hours.
Here is my code:
TrafficIncidentNotificationRadiusCalculator class
namespace TrafficIncident
{
public class TrafficIncidentNotificationRadiusCalculator
{
public double meters;
public double CONFIGURED_NOTIFICATION_RADIUS
{
get { return CONFIGURED_NOTIFICATION_RADIUS; }
set { CONFIGURED_NOTIFICATION_RADIUS = meters; }
}
public List<string> GetNotificationRecipientsList(List<User> users, List<UserLocationUpdate> userLocation, TrafficIncidentReport report)
{
int i = 0;
List<string> userNotificationIds = new List<string>();
while (i < userLocation.Count)
{
UserLocationUpdate userLoc = userLocation.ElementAt(i);
userNotificationIds.Add(userLoc.userNotificationId);
Console.WriteLine(userNotificationIds.ElementAt(i));
i++;
}
return userNotificationIds;
}
}
}
TrafficIncidentReport class
namespace TrafficIncident
{
public class TrafficIncidentReport
{
public double[] incidentLocation;
public double latitude
{
get { return latitude; }
set { latitude = value; }
}
public double longitude
{
get { return longitude; }
set { longitude = value; }
}
public void SetIncidentLocation()
{
incidentLocation = new double[] { latitude, longitude };
}
public double[] GetIncidentLocation()
{
return incidentLocation;
}
}
}
User class
namespace TrafficIncident
{
public class User
{
public string userFName
{
get { return userFName; }
set { userFName = value; }
}
public string userLName
{
get { return userLName; }
set { userLName = value; }
}
}
}
UserLocationUpdate class
namespace TrafficIncident
{
public class UserLocationUpdate
{
public string userNotificationId
{
get { return userNotificationId; }
set { userNotificationId = value; }
}
public double lastKnownLatitude
{
get { return lastKnownLatitude; }
set { lastKnownLatitude = value; }
}
public double lastKnownLongitude
{
get { return lastKnownLongitude; }
set { lastKnownLongitude = value; }
}
}
}
And then this is the console application that the class library is running from:
namespace ClassLibraryTestApp
{
class Program
{
static void Main(string[] args)
{
List<User> users = new List<User>();
List<UserLocationUpdate> userLocation = new List<UserLocationUpdate>();
User user1 = new User();
user1.userFName = "Scott";
user1.userFName = "Gersbank";
users.Add(user1);
User user2 = new User();
user2.userFName = "John";
user2.userFName = "Smith";
users.Add(user2);
User user3 = new User();
user3.userFName = "James";
user3.userFName = "Moore";
users.Add(user3);
UserLocationUpdate user1Location = new UserLocationUpdate();
user1Location.lastKnownLatitude = 0;
user1Location.lastKnownLongitude = 0;
user1Location.userNotificationId = "user1";
userLocation.Add(user1Location);
UserLocationUpdate user2Location = new UserLocationUpdate();
user1Location.lastKnownLatitude = 1;
user1Location.lastKnownLongitude = 1;
user1Location.userNotificationId = "user2";
userLocation.Add(user2Location);
UserLocationUpdate user3Location = new UserLocationUpdate();
user1Location.lastKnownLatitude = 2;
user1Location.lastKnownLongitude = 2;
user1Location.userNotificationId = "user3";
userLocation.Add(user3Location);
TrafficIncidentReport trafficReport = new TrafficIncidentReport();
trafficReport.latitude = 1;
trafficReport.longitude = 1;
trafficReport.SetIncidentLocation();
TrafficIncidentNotificationRadiusCalculator TINRC = new TrafficIncidentNotificationRadiusCalculator();
TINRC.meters = 20000;
TINRC.GetNotificationRecipientsList(users, userLocation, trafficReport);
}
}
}
This is not a right way to create properties, define a private field, then the property itself: In your case it will call recursively the set_latitude() method and cause a stack overflow exception.
Wrong:
public double latitude
{
get { return latitude; }
set { latitude = value; }
}
Right:
private double latitude
public double Latitude
{
get { return latitude; }
set { latitude = value; }
}
Or use Auto-Implemented Properties:
public double Latitude { get; set; }
Your code starts with a recursive assignment, The first recursion is here :
public double meters;
public double CONFIGURED_NOTIFICATION_RADIUS
{
get { return CONFIGURED_NOTIFICATION_RADIUS; }
set { CONFIGURED_NOTIFICATION_RADIUS = meters; }
}
What's wrong:
Whenever you set some value to a property it's setter will trigger,
and whenever you access the value of a property the setter will
trigger. in the above mentioned case, you are assigning the property
value in it's setter which will repeatedly trigger the setter and
hance you get the exception
See all of your getter and setter are wrong, You should use a backup variable or else use them as {get;set}. In the case of userNotificationId you should define the property as like the following:
private _UserNotificationId
public string UserNotificationId
{
get { return _UserNotificationId; }
set { _UserNotificationId= value; }
}
Or simply
public string UserNotificationId { get; set; }
How can I return the calculated value _B where one of the arguments is value _A and hard coded data for example "1" ?
class Example
{
private static int _A;
private static int _B = _A + 1;
public int GetA
{
get
{
return _A;
}
set
{
_A = value;
}
}
public int GetB
{
get
{
return _B;
}
}
}
I`m always getting back just "1".
Example example = new Example();
example.GetA = 20; // set { }
Console.WriteLine(example.GetB); // get { }
I was hoping to get 21.
When you assign a value to a property in the same line as the declaration, the value is set only one time.
You have at least two options, use new property declaration with arrow function. Or set the value in the setter of the dependent property.
class Example
{
private static int _A;
private static int GetB => _A + 1;
public int GetA
{
get
{
return _A;
}
set
{
_A = value;
}
}
}
Or
class Example
{
private static int _A;
private static int _B;
public int GetA
{
get
{
return _A;
}
set
{
_A = value;
_B = _A + 1;
}
}
public int GetB
{
get
{
return _B;
}
}
}
My program throws this exception:
System.StackOverflowException
when the compiler executes the set property.
The wine class:
class wine
{
public int year;
public string name;
public static int no = 5;
public wine(int x, string y)
{
year = x;
name = y;
no++;
}
public int price
{
get
{
return no * 5;
}
set
{
price = value;
}
}
}
The Program class:
class Program
{
static void Main(string[] args)
{
wine w1 = new wine(1820, "Jack Daniels");
Console.WriteLine("price is " + w1.price);
w1.price = 90;
Console.WriteLine(w1.price);
Console.ReadLine();
}
}
When setting the price property, you invoke the setter, which invokes the setter which invokes the setter, etc..
Solution:
public int _price;
public int price
{
get
{
return no * 5;
}
set
{
_price = value;
}
}
You're setting the value of the setter from within the setter. This is an infinite loop, hence the StackOverflowException.
You probably meant to use a backing field no as per your getter:
public int price
{
get
{
return no * 5;
}
set
{
no = value/5;
}
}
or perhaps use its own backing field.
private int _price;
public int price
{
get
{
return _price;
}
set
{
_price = value;;
}
}
However, if the latter is the case, you dont need the backing field at all, you can use an auto property:
public int price { get; set; } // same as above code!
(Side note: Properties should start with an uppercase - Price not price)
Your property setter calls itself when you set any value, thus it produces an stack overflow, I think what you wanted to do was:
public int price
{
get
{
return no * 5;
}
set
{
no = value / 5;
}
}
I am totally unable to access the outer class attributes inside the inner class ...
even if i make object of outer class,, in inner class*which makes no sense in composition design* .. even then i cant access them ..
is there a way by which i can access these outer class attributes ?
Scenario is that there is some sports car which is constructed only if the customers who want to buy it exists! ..
namespace composition{
public class CustomCar
{
#region Attributes
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
#endregion
#region properties
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
#endregion
#region methods
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string s1, string pno, double c, string s2, double n, double bc)
{
this.Name = s1;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = s2;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
#endregion
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
}
}
There is nothing stopping you having a reference in the CarCustomer to the CustomCar object as well. This would then give you a one to one reference between the object. Were you instaiate this object is up to you in the Constructor of the CustomCar
public CustomCar(arguments)
{
this.Customer.CustomCar = this;
}
Or you could set it in the sets on the property accessors up to you. Try this
public class CustomCar
{
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string name, string pno, double c, string customerName, double n, double bc)
{
this.Name = name;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = customerName;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
this.Customer.Car = this;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
}
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
private CustomCar customer;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CustomCar Car
{
get{return customer;}
set{customer = value;}
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
Of course you can't access them. You've set their protection level to private. In order to get at them from an external resource their protection level has to be in line with the access level needed. In this case you should be able to change the modifier to protected and be able to access them.
However, looking at your class design, I think you would be better served using the automatic getter/setter syntax. You aren't doing anything particularly special in your property definitions, so it would make sense to get rid of the private variables and change your properties to this:
public string Name { get; set; }
public double Cost { get; set; }
public string PlateNo { get; set; }
public CarCustomer Customer { get; set; }
You'll still have public access to the variables through the properties and you won't have all the messiness of the extra variables.