The question: How can i link the user input to a specific constructor and create an object when the user clicks on Add.
How i created my project:
I created a console application. A class named car with the following attributes:
Brand name
Type
Mileage
Commissioning date
Numberplate
Horsepower
Number of gears
Number of seats
Volume of the trunk
Fuel consumption
2 Constructors: 1 with everything except number of seats. Second with everything except number of gears.
A method that adds to the fuel consumption depending on how many numbers of gears or number of seats.
Everything works well. I now created a windows form. Changed output type to windows form instead of console.
For the windows form:
The user has to choose between 2 options: A sports car or a family car. Depending on which option the user chooses, for the sports car all attributes except for number of seats. For the family car, everything except for number of gears. The user has to fill in the name of the car, type, etc.
Then the user needs to click on the button named Add in order to see the consumption of the vehicle. Later in the project, i need to create it so that the user is able to delete it by typing in the numberplate.
namespace Sportwagens {
public class Wagen
{
string Merk;
string Type;
int Aantalkm;
DateTime Ingebruiknamedatum;
string Nummerplaat;
int Pk;
int Brandstofverbruik;
public class Sportwagen : Wagen
{
int Aantalvitessen;
public Sportwagen(string merk, string type, int aantalkm, DateTime ingebruiknamedatum, string nummerplaat, int pk, int aantalvitessen, int brandstofverbruik)
{
Merk = merk;
Type = type;
Aantalkm = aantalkm;
Ingebruiknamedatum = ingebruiknamedatum;
Nummerplaat = nummerplaat;
Pk = pk;
Aantalvitessen = aantalvitessen;
Brandstofverbruik = brandstofverbruik;
}
public int vermeerderingbrandsotfverbruiksportwagen()
{
if (Aantalvitessen >= 6)
{
Brandstofverbruik += 2;
}
return Brandstofverbruik;
}
}
class Gezinswagen : Wagen
{
int Aantalzitplaatsen;
int Koffervolume;
public Gezinswagen(string merk, string type, int aantalkm, DateTime ingebruiknamedatum, string nummerplaat, int pk, int aantalzitplaatsen, int koffervolume, int brandstofverbruik)
{
Merk = merk;
Type = type;
Aantalkm = aantalkm;
Ingebruiknamedatum = ingebruiknamedatum;
Nummerplaat = nummerplaat;
Pk = pk;
Aantalzitplaatsen = aantalzitplaatsen;
Koffervolume = koffervolume;
Brandstofverbruik = brandstofverbruik;
}
public int vermeerderingbrandsotfverbruikgezinswagen()
{
if (Aantalzitplaatsen >= 7)
{
Brandstofverbruik += 1;
}
return Brandstofverbruik;
}
}
public Wagen()
{
}
public Wagen(string merk, string type, int aantalkm, DateTime ingebruiknamedatum, string nummerplaat)
{
Merk = merk;
Type = type;
Aantalkm = aantalkm;
Ingebruiknamedatum = ingebruiknamedatum;
Nummerplaat = nummerplaat;
}
Click here to see how the form looks like
If the 'car' object is instantiated when the user chooses between the two options, you could simply change the order of the arguments in each constructor (assuming that there are arguments of different types).
For example, if one constructor was:
public Car(string brandName, string type, double mileage ...)
{
...
}
And the other was:
public Car(string brandName, double mileage, string type ...)
{
...
}
You could force the class to use one or the other based on the order in which you give the parameters. However this is not good practice.
From your description, it sounds as though you should create two 'subclasses', (SportsCar and FamilyCar) and use inheritance to achieve your goal, or composition.
Double click on the "Toevoegen" button in the form editor. That should create a method that looks a bit like this:
private void button1_Click(object sender, EventArgs e)
{
}
Outside the method, declare an instance of the 'Wagen' class like so:
Wagen mijnWagen;
Then, inside the button_click method, initialise the instance of the wagen object as follows:
if (//"Sportswagen is selected")
{
mijnWagen = new Sportwagen(merk, type etc. as filled in on form);
}
else
{
mijnWagen = new Gezinswagen(merk, type etc. as filled in on form);
}
Now, when the button is clicked, the object mijnWagen will be initialised to whichever type of car they selected.
Related
I have fairly complicated ui system that i want to simplify. What I want is to make separate classes with command and fluent builder pattern that which instances I will create at the beginning of the app and then execute when needed, something like this:
public interface IGuiCommand
{
void Execute();
void Execute(Action onComplete = null);
}
public class GuiCommandBuilder : IGuiCommand
{
public void Execute()
{
}
public void Execute(Action onComplete = null)
{
}
}
public class GuiCommandTest : GuiCommandBuilder
{
private int _id;
public GuiCommandTest()
{
}
public GuiCommandTest Setup(int id)
{
_id = id;
return this;
}
}
so I can do this:
// create command
var GuiRoomSelectionCommand = new GuiCommandTest();
// setup and execute (I have to provide additional data in order
// command to work correctly, some commands don't need additional data)
GuiRoomSelectionCommand
.Setup(223)
.Execute(() =>
{
});
The problem I am having is that I want to create all commands
at the start of the app and store them for later easy access, but I can't just
store them as IGuiCommand since I will need a concrete instance in order to setup the
concrete commands? How to do that, or if any other setup is better approach?
I want that others can easily see what commands are there and how to add more of them
if needed or easily modify the existing ones in separate classes so that main controller
doesn't change to much but only specific commands
Define an ICommandParameter interface to indicate the name of the parameter and its current value.
You can create different types of parameters by implementing this interface:
public ICommandParameter
{
string Name {get;set;}
object ObjectValue {get;set;}
}
public IDoubleParameter : ICommandParameter
{
double MinValue {get;set;}
double MaxValue {get;set;}
double Number {get;set;}
int DecimalsCount {get;set;}
}
public IBoolParameter : ICommandParameter
{
bool Checked {get;set;}
}
public IAnimalsParameter : ICommandParameter
{
Animal Animal {get;set;} // Animal is an enum with a list of values
}
Now, your IGuiCommand can have a list of ICommandParameter that you can initialize in the constructor of your command.
In GuiCommandBuilder (or in other class if you consider) you can manage the parameters. You have access to the command parameters and show/update using some Forms.
For example, in your GuiRoomSelectionCommand you can access to the parameters list, with a simgle parameter "Number of rooms" that you can see (you can check/try cast) that implements IDoubleParameter with this values:
Name = "Number of rooms"
ObjectValue = 2
MinValue = 1
MaxValue = 10
Number = 2 // Usually a cast of ObjectValue interface
DecimalsCount = 0
You can create a Form in which you add some controls depending of parameters type. For previous example, you can add a Label for Name and a NumericUpDown for the value (settings decimals, minimum and maximum). You initialize the numeric with the Number property. And when you click Ok in the dialog, you can update de Number property with the numeric value.
For any Enum property, you can add a ComboBox to show/edit it's value. For a bool property, a CheckBox and so on.
You need spend some time to create the controls for any type of property to manage but, at the end, most of properies are of basic types. There aren't lots of controls.
I have an assignment (bunch of oop stuff, polymorphism and inheritance) and amongst other things I have to do the following:
I need to add an abstract method to the class Vehicle (called calculateOccupancy()) which has to return the % of the leftover space in a vehicle. I then have to implement that in my derived classes. The issue here is, I have 3 derived classes, two of them have 2 attributes and one has 3. So how do I make my abstract method, so that it can accept 2 or 3 arguments.
I have to add a unchangeable property to the class Person, and the property has to return the first letter of the name and surname, divided by a dot.
namespace Example
{
abstract class Vehicle
{
//class member variables, most likely unnecessary for the questions
private Person driver;
private string vehicleBrand;
private string vehicleType;
private double fuelConsumption;
private double gasTankSize;
private string fuelType;
//the default constructor
public Vehicle()
{}
//The abstract method from question 2
// how to make it so that it wont error when I need to
//put in 3 variables instead of two, meaning, how would I add int c
public abstract double calculateOccupancy (int a, int b);
//The derived class that implements the method
class Bus : Vehicle
{
private int allSeats;
private int allStandingSeats;
private int busPassengers; //the number of passengers
//the constructor
public Bus (int a, int b, int c)
{
allSeats=a;
allStandingSeats=b;
busPassengers=c;
}
//the abstract method
// needs to take in int b (standing seats)
public override double calculateOccupancy(int a, int c)
{
//this code calculates the leftover space in the vehicle
double busSpace=(busPassengers*100) / allSeats;
return busSpace;
//same code for the leftover standing space (int c)
}
}
}
class Person
{
protected string name;
protected string lastName;
//question 1
//properties for char gender
protected char gender;
//question 3
protected readonly string initials;
//the code errors, at the get/set
public char Gender
{
get{ return gender; }
set {gender=value;}
}
/*and the property im not sure how to make
public string Initials{}
*/
}
I hope the comments add some clarity, rather than confusion, thank you for your help everybody.
Assumption going forward - I threw some of your variable names into Google Translate and it seems to be Slovenian. I'm assuming that going forward which helped me make some clarity of what your code does.
1) Replace - If you already have a variable that is a char representing spol then I believe you're supposed to use the new enum type you are to create to represent it.
public enum Spol
{
Moski = 0,
Zenska = 1
}
Change:
protected char spol;
public char Spol
{
get{ return spol; }
set {spol=value;}
}
To: public Spol Spol { get; set; }
2) Defaults & Conditions - Use int c = 0 as your 3rd parameter and use a formula/algorithm that ignores it if it is the default value.
3) Getters - This property doesn't have a setter and therefore cannot be changed (directly).
public string GiveThisAName
{
get
{
if (String.IsNullOrWhiteSpace(ime))
{
return null;
}
if (String.IsNullOrWhiteSpace(priimek))
{
return null;
}
return ime[0] + '.' + priimek[0];
}
}
Notes
1) Heavily recommend making the parameters of your capacity function (i.e. izracunajZasedenost(int a, int b)) to be named something useful (i.e. a name descriptive of what they do) other than a and b.
2) For the record, #1 seems more like an appropriate question for your instructor, teacher, or whoever gave you this assignment.
Give the "optional" values a value when you create the abstract method
public abstract double izracunajZasedenost (int a = -1, int b = -1)
{
if (a == -1){
//do method with ignoring a
}
};
I am looking for a way to do arbitrary class instantion as well as attribute assignement and possibly method calling in .Net and preferrably C#. Since arbitrary is too broad a word let me tell you what I am after.
Let's say I have a DLL (objects.dll) that contains:
public class Person
{
// Field
public string name;
// Constructor that takes no arguments.
public Person()
{
name = "unknown";
}
// Constructor that takes one argument.
public Person(string nm)
{
name = nm;
}
// Method
public void SetName(string newName)
{
name = newName;
}
}
public class Table
{
// Field
public int width;
public int lenth;
public int height;
// Constructor that takes no arguments.
public Table()
{
width = 0;
length = 0;
height = 0
}
// Constructor that takes three arguments.
public Table(int w, int l, int h)
{
width = w;
length = l;
height = h;
}
// Method
public void SetWLH(int w, int l, int h)
{
width = w;
length = l;
height = h;
}
}
public class Printer
{
public Printer(){}
public void printAPerson(Person p)
{
//do stuff with p
}
public void printATable(Table t)
{
// do stuff with t
}
}
I want to be able to instantiate either of the classes above, set attribute values and call methods at runtime from a different program in the most generic possible. eg. lets say I hame a programm called myprog.exe, i want to be able to do the following
myprog.exe objects.dll Person name testname Printer printAPerson
where:
objects.dll is the dll that contains all required classes
Person is the first I will instantiate name is its attribute
testname is the value I will assign to this attribute
Printer is the class I will use for printing
printAPerson is the method in the Printer class I need to call with the specified object as a parameter.
As you can see, in the best case for my use scenario, neither of the objects and classes are/will be known at compile time so I would like to be as non-casting as possible. If that is not possible I will take what I can.
I have seen this, How to use reflection to call a method and pass parameters whose types are unknown at compile time?, which to my limited knowledge kind of does what I want minus the casting bits or I could be mistaken.
Thanks a lot!
Instead of using Reflection you could use dynamic. But this requires that the Printer class and others are changed. And you would loose intellisense and compile time checks.
public class Printer
{
public Printer() { }
public void printAPerson(dynamic p)
{
//do stuff with p
Console.WriteLine("Person name: " + p.name);
}
public void printATable(dynamic t)
{
// do stuff with t
Console.WriteLine("printATable(Table p) is called");
}
}
public class TestDynamic
{
public static void Test()
{
// To get the type by name,
// the full type name (namespace + type name) is needed
Type personType = Type.GetType("StackOverflowCodes.Person");
object personObj = Activator.CreateInstance(personType);
// Implicit cast to dynamic
dynamic person = personObj;
person.SetName("Alan Turing");
Type printerType = Type.GetType("StackOverflowCodes.Printer");
object printerObj = Activator.CreateInstance(printerType);
dynamic printer = printerObj;
printer.printAPerson(personObj);
}
}
Are you flexible concerning your executable input format? If so, you could do what you want by having a convention. I would do this using a JSON structure like this one:
{
Command : "",
Arguments : {
Argument1 : 0,
Argument2 : { }, // can be another complex object
Argument3 : [] // an empty array maybe ...
}
}
Where Command would be something like "ClassName.MethodName", Arguments will be a JSON object that each object property represents your method parameter.
In your executable, you must parse this JSON using a library (example http://www.newtonsoft.com/json) and use reflection to deserialize every JSON object parameter and call your method. If you cannot get it work, please let me know I will try to make an example (if I will have time, this night because I am at work right now).
For your case you just want to print an object of type Person to the printer right? You could execute a command like this:
{
Command : "Printer.PrintAPerson",
Arguments : {
p : { name : 'george' }
}
}
If you want to rely on a standard protocol, please check the JSON-RPC protocol: http://json-rpc.org/wiki/specification
How can I edit parameters of my objects added to ListBox?
Already I have something like this:
public class Car
{
protected double aa;
protected string n;
public Car(double aa, string n)
{
this.a = aa;
this.n = n;
}
public virtual double Speed()
{
return 0;
}
public class Car111 : Car
{
public double A { get; set; }
public string Name { get; set; }
public Car111(double aa, string n)
: base(aa, n)
{
A = aa;
Name = n;
}
public class Car222 : Car
{
public double A { get; set; }
public string Name { get; set; }
public Car111(double a, string n)
: base(aa, n)
{
A = aa;
Name = n;
}
public override string ToString()
{
return Name;
}
listBox1.Items.Add(new Car111(aa, "MyCar")); //add obcject to listbox
listBox1.Items.Add(new Car111(aa, "MyCar")); //add obcject to listbox
private void button5_Click(object sender, EventArgs e)
{
Car111 item = (Car111)listBox1.SelectedItem;
if (item != null)
item.A = Convert.ToDouble(textBox8.Text); //There is a problem
}
}
}
}
A don't know what to do to change "aa" parameter in Car111 and Car222 class. How can I add the summary Speed of Cars being adding to listbox?
I'm not entirely sure I understand your question and the fact that the code you have provided doesn't compile makes it a bit more difficult, however I'll take a stab at it... There are 2 things I can think of that you may be asking/having trouble with
FIRST
Let's start with the end of your post:
A don't know what to do to change "aa" parameter in Car111 and Car222
class. How can I add the summary Speed of Cars being adding to
listbox?
I don't see anything in your code that refers to speed, other than a virtual method that always returns 0. Based on the context of your question, however, I'm guessing that perhaps you are using aa from the base object, Car. Next, I'd like to look at your last line of code:
item.A = Convert.ToDouble(textBox8.Text); //There is a problem
Note that you are not setting aa here, you are setting A. If you are trying to expose aa with A, then instead of declaring A as
public double A { get; set; }
you would instead need to do this:
public double A { get{return aa;} set{aa = value;} }
The reason for this is because when you use auto-properties, the compiler creates a backing variable in the background for you; obviously, it isn't going to know that you want it to be backed with aa (or anything else) unless you tell it so. Note that this applies to n and Name, too.
While we are on the topic, if all of your derived classes are going to have an A and Name the expose aa and n, respectively, then you might as well put them in the parent class.
SECOND
Looking at the first line of your question:
How can I edit parameters of my objects added to ListBox?
I think you are saying that you want the listbox to show a new value. If that is the case, I would question how you are displaying your car data in the listbox. When you execute line of your code,
listBox1.Items.Add(new Car111(aa, "MyCar")); //add obcject to listbox
The listbox would add an item, but unless there is some work going on that you are not showing us, then what would show up is <yourAssemblyName>.Car111 (unless Car111 is also supposed to have a ToString like Car222, in which case you would show the name, "MyCar".)
Either way, when you call
item.A = Convert.ToDouble(textBox8.Text); //There is a problem
That isn't going to update anything your listbox is showing.
Suggestion:
I don't see anything in your example that necessitates the added complexity of inheritance. Perhaps there is more that you are not showing, but based on what you have here, and based on the assumptions I have made, I would refactor your code to look something like this:
public class Car
{
//update aa, n, and A to reflect what they represent.
//I'm guessing that n represents "name" and "aa" represents "speed"
//Unless you need inheritance, you can use private instead of protected
private double _speed;
private string _name;
//I'm guessing "A" represents "Speed".
public double Speed
{
get { return _speed; }
set { _speed = value; }
}
//This was in your base class, but you don't need it if
// "Speed" (what was "A") will work up here
//public virtual double Speed()
//{
// return 0;
//}
public string Name
{
get { return _name; }
set { _name = value; }
}
//parameters should reflect what they represent, as well
public Car(double speed, string name)
{
this._speed = speed;
this._name = name;
}
public override string ToString()
{
//return Name;
//If you want to show the name and the speed in the listbox
//you could use the following:
return string.Format("{0} is going {1}", Name, Speed);
}
}
Then you can add it the way you were, except w/o inheritance (unless needed):
listBox1.Items.Add(new Car(travelingSpeed, "MyCar")); //add object to listbox
listBox1.Items.Add(new Car(travelingSpeed, "MyCar")); //add object to listbox
Finally, unless you have data binding going on, if you simply update the object, the listbox won't update. You will need to tell the listbox to update. Here is one way to do that:
private void button5_Click(object sender, EventArgs e)
{
Car c = (Car)listBox1.SelectedItem;
if (c == null)
return;
if (!Double.TryParse(textBox8.Text, out c.Speed))
return;
int idx = listBox1.Items.IndexOf(listBox1.SelectedItem);
listBox1.Items.Remove(listBox1.SelectedItem);
listBox1.Items.Insert(idx, c);
}
This Is my Assignment, I am having Troubles Getting my Class To Work With main for, Can Someone please Help Me, This is due on Tuesday and I have been hitting a brick wall in every approach I have tried. all my class and my forms are posted. Please Help me I am totally lost and frustrated
1.Employee and ProductionWorker Classes
Create an Employee class that has properties for the following data:
•Employee name
•Employee number
Next, create a class named ProductionWorker that is derived from the Employee class.
The ProductionWorker class should have properties to hold the following data:
•Shift number ( an integer, such as 1, 2, or 3)
•Hourly pay rate The workday is divided into two shifts: day and night.
The Shift property will hold an integer value representing the shift that the employee works. The day shift is shift 1 and the night shift is shift 2.
Create an application that creates an object of the ProductionWorker class and lets the user enter data for each of the object’s properties. Retrieve the object’s properties and display their values.
This Is My Employee Reference Chart. To Store Their Names And I.D Numbers I am getting no compiling errors on this class, however I am not sure if I am doing this correctly because in my main I get a compiling error.
I assume I need an array to store all the data that will be inputted into my TextBox in visual
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Employee_References
{
class Roster
{
// Field for name, ID, dept, and position
private const int NAMES = 100;
private static string [] employee = new string [NAMES];
private const int NUMBER = 100;
private static int [] id = new int [NUMBER];
private int total = 0;
public void Employee()
{
total = 0;
}
// This will recieve input from my main
public static void employeeName (string [] xArray)
{
for (int index = 0; index < xArray.Length; index++)
{
xArray[index] = employee[NAMES];
}
}
// This will recieve input from my main
public static void idNumber ( int [] zArray)
{
for (int index = 0; index < zArray.Length; index++)
{
zArray[index] = id[NUMBER];
}
}
}
}
This will be my next class that is derived from my first class as my assignment requested. This class is suppose to store the shift numbers 1 through for 4, and an hourly wage setter for a Day and Night Shift. I am getting one compiling error in this class that says " The left-hand side of an assignment must be a variable, property or indexer" I am not sure What it is telling me, can someone please explain what it is trying to tell me. Am I doing this correctly?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Employee_References
{
class References : Roster
{
// Field for name, ID, dept, and position
private int shift;
private static const double PAYRATEDAY = 12.75;
private static const double PAYRATENIGHT = 15.75;
public void Employee()
{
}
// This will recieve input from my main
public int shifts
{
set {shift = value;} // this set the recieve value of name one and set it to name1
get {return shift; } //this will get name1 and send it to my main.
}
// This will recieve input from my main
public double payrate1
{
set { PAYRATEDAY = value; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
get { return PAYRATEDAY; }
}
// This will recieve input from my main
public double payrate2
{
get { return PAYRATENIGHT; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
set { PAYRATENIGHT = value; }
}
}
This is my Form, I am trying to send my input values into my class my "Roster" class That has an array of 100. How ever I keep getting a compiling error that says " Cannot assign to 'employeeName' because it is a 'method group". I am not sure What It is telling me can some one explain this to me, and give me some pointer on how to do this
using System;
using System.Windows.Forms;
namespace Employee_References
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Roster Chart = new Roster();
Chart.employeeName = name.Text; // Error **Cannot assign to 'employeeName' because it is a 'method group**".
}
}
}
employeeName() is a method and you are trying to assign it a value.
Looks like you want to try and pass an array of names to it as a parameter
//first define and populate myArray
Chart.employeeName(myArray)
You say
private static const double PAYRATEDAY = 12.75;
Then
public double payrate1
{
set { PAYRATEDAY = value; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
get { return PAYRATEDAY; }
}
Why do you declare the field constant if you are changing it?
Also, I think you'd be better off using lists instead of arrays, so that it can grow dynamically as much as it needs instead of being limited by a fix number.