If I have a class, let's say Car.
class Car {
private Color m_Color;
private int m_Passengers;
}
Now, when I have this class at this state, I'm implementing this on X number of places in my software. Later on, my boss says he also want to store the max speed of the car. By all means, he is a nice guy and should have his property added.
class Car {
private Color m_Color;
private int m_Passengers;
private int m_MaxSpeed;
}
With this workflow, we might have something like this after a while
class Car {
private Color m_Color;
private int m_Passengers;
private int m_MaxSpeed;
private int m_Year;
private List<Seats> m_Seats;
private DateTime m_LatestCHeckup;
private double m_GasUsage;
}
Which is ok, but the 1st and 2nd version of the class is already implemented with fewer properties. How can I make sure, that if I add a property on a object that property must be used on all other objects initiated from the same class?
EDIT:
To clear it up.
I use this for my first car:
Car c = new Car();
c.m_Color = Color.White;
c.m_Passengers = 4;
and this for my 2nd car:
Car c2 = new Car();
c2.m_Color = Color.White;
c2.m_Passengers = 4;
c2.m_MaxSpeed=200;
and 3rd car
Car c3 = new Car();
c3.m_Color = Color.Green;
c3.m_Passengers = 8;
c3.m_MaxSpeed=180;
c3.m_Year = 2000;
c3.m_Seats = mySeatList;
c3.m_LatestCheckup = Datetime.Now;
c3.m_GasUsage=1.8;
I want to make sure that GasUsage is added on c and c2 when I've added it to the class. But c and c2 was created long time ago when GasUsage didnt exist. How do I prevent an object to not have all properties used? I might have one class, but 2000 objects.
The reason I want this behaviour is because I might loop through all the car objects and calculate for example how much gas they've used. Or similiar. If not all objects have a value in GasUsage that calc would fail.
If you have required properties that need to be initialised you should declare them in the constructor. Any optional values can be made into properties.
If you add any required properties to your Car class you should add them to the constructor, then the compilation will fail until previously-created values are fixed.
From your comment it looks like you want to add an interface with all the declared properties, then make them all constructor parameters in your implementing class:
public interface ICar {
Color Color { get; }
int Passengers { get; }
...
double GasUsage { get; }
}
class Car : ICar {
public Car(Color color, int passengers, int maxSpeed, ..., double gasUsage) {
this.m_Color = color;
this.m_Passengers = passengers;
...
this.m_GasUsage
}
private Color m_Color;
private int m_Passengers;
}
The initialization of the class instances could also be done with an constructor that demands all properties; all instatiations would then become syntactically incorrect as soon as a new property is added.
Assuming that 'Property must be used' means that you expect the instantiated objects to set a value for each of the new properties then you either change the constructor to require the new properties, set a default value for the new properties or raise an exception if a method on the object is called that requires a value to be set.
First version of the car class:
class Car
{
public Car(Color mColor, int mPassengers)
{
m_Color = mColor;
m_Passengers = mPassengers;
}
private Color m_Color;
private int m_Passengers;
}
Second version of the car class with constructor that has default value:
class Car
{
public Car(Color mColor, int mPassengers, int mMaxSpeed = 130)
{
m_Color = mColor;
m_Passengers = mPassengers;
m_MaxSpeed = mMaxSpeed;
}
private Color m_Color;
private int m_Passengers;
private int m_MaxSpeed;
}
Related
I am looking for a way to determine the number of struct objects that are created in my program. It is for educational purposes.
I found this answer on SO, which works for classes: https://stackoverflow.com/a/12276687/363224. So I tried to do something similar with a struct, but as expected it doesn't work like that.
public struct Car
{
public string brand;
public static int ObjectsConstructed { get; private set; }
public Car(string brand)
{
this.brand = brand;
ObjectsConstructed++;
}
}
...
Car car1 = new Car("VW");
Car car2 = car1; // How can we increment the ObjectsConstructed?
List<Car> carList = new List<Car>();
carList.Add(car1); // How can we increment the ObjectsConstructed?
The Car(string) constructor is not called, because the copy of the struct object is called some kind of memcpy and doesn't go through the constructor. A struct also doesn't allow explicit parameterless constructors.
How does one make sort of a copy constructor that can be handled? Or is there another way to get this information out of the runtime via reflection?
EDIT
I wrote a test that shows what I mean:
// This test passes, firstCar and sameCar are not the same.
[TestMethod]
public void HowManyTimesIsACarCreated()
{
Car firstCar = new Car();
Car sameCar = firstCar;
sameCar.brand = "Opel";
// It seems that you can change sameCar without changing firstCar
Assert.AreNotEqual(firstCar.brand, sameCar.brand);
// This one is tricky, because firstCar and sameCar are passed as parameters, so new objects would again be created as I would see it.
Assert.IsFalse(ReferenceEquals(firstCar, sameCar));
}
firstCar and sameCar do not point to the same object, since I can change the brand if sameCar, but firstCar is still the same.
I'm working on a app on C# Visual Studio '13, and I just hit a brickwall - a newbie brickwall I bet. I have a class - lets say it's a car class. It isn't, but it's a decent example for this question.
Now, I'd like to create - I'm not sure this is the right terminology - templates, from which I'd like to create instances. These created instances will be stored in a List<Car> object.
Let's just say the car class has name, model year and mileage attributes. I'd like to be able to create a template, where I can call up a constructor to create a car with a preset name and model year, but a randomized mileage - and have a couple of different ones. Maybe use it in a constructor in such a way, that I have a few sets of presets - or templates - e.g. '99 BMW, '03 Merc and a '79 Lada. When I call the constructor, I'd like it to pick one of these templates, and add a random mileage.
The adding random mileage is not a problem. Matter of fact, there is no problem with building this other than the fact that for the life of me, I can't figure out how to do templates in a constructor.
One of the easiest solutions for some hardcoded, predefined instance values is the factory pattern. For the following Car class:
public class Car
{
public string Model { get; private set; }
public int Year { get; private set; }
public Color Color { get; private set; }
public int Mileage { get; private set; }
// ...
public Car(string model, int year, Color color, int mileage)
{
Model = model;
Year = year;
Color = color;
Mileage = mileage;
}
}
you can create CarFactory as suggested by Henk Holterman in his comment. For example:
public class CarFactory
{
public CarFactory()
{
random = new Random();
}
public Car CreateBMW99WithRandomMileage(Color color)
{
return new Car("BMW", 1999, color, random.Next());
}
public Car Create03BlackMerc(int mileage)
{
return new Car("Mercedes", 2003, Colors.Black, mileage);
}
public Car Create79Lada(Color color, int mileage)
{
return new Car("Lada", 1979, color, mileage);
}
// ...
private Random random;
}
As you can see you have many possibilities when choosing which attributes to fix, which should be random, and which can be left out as configurable.
Another, similar, pattern you can employ here is the prototype pattern.
Here is how you can combine these two patterns to create a random car:
public class CarFactory
{
public CarFactory()
{
random = new Random();
black99BMW = new Car("BMW", 1999, Colors.Black, 0);
black03Merc = new Car("Mercedes", 2003, Colors.Black, 0);
black79Lada = new Car("Lada", 1979, Colors.Black, 0);
// ...
allCars = new Car[] { black99BMW, black03Merc, black79Lada };
}
public Car CreateBMW99WithRandomMileage(Color color)
{
return black99BMW.Clone(color, random.Next());
}
public Car Create03BlackMerc(int mileage)
{
return black03Merc.Clone(Colors.Black, random.Next());
}
public Car Create79Lada(Color color, int mileage)
{
return black79Lada.Clone(color, mileage);
}
public Car CreateRandomCar()
{
var index = random.Next(allCars.Length);
Color color = // pick random color
int mileage = random.Next();
return allCars[index].Clone(color, mileage);
}
private Car black99BMW;
private Car black03Merc;
private Car black79Lada;
private Car[] allCars;
}
Possibilities are countless - this is just a simple example, and does not necessary fit your scenario best. However, usually and especially for beginners, it is better to implement something to see how does it work, to see its advantages and flaws with your own eyes, and then try to improve it.
I have the following objects :
Formula
Stock
Counter
etc ...
all these objects are called indicators and have common properties (Id, Name, Value...).
Each entity has its own properties:
Formula: FormulaExpression, FormulaCode, OperandsList ...
Stock: StockValue, StockLimit...
Counter: CounterIndex...
etc ...
So logically, i have to make indicator class containing the common properties, and for each entity i have to create a class that inherits from indicator.
Formula is a special indicator that can contain any type of indicators. The formula's indicators are named operands.
the operand object has the following properties:
operandId, operandCode, operandIndex
when i want to list the formula operands, i want to get objects which inherit from indicator, operand and entity type (create an object that have indicators properties, operand properties and stock properties for example)
which design pattern or which architecture allows me to have this behaviour?
To explain more the problem
The entities (Formula, stock, Counter..) are Indicators and not necessary Operands, Operands are Indicators too. Object Indicator is the primitive type of entities, we can create an Indicator and then decorate it to become a Formula for example and than decorate it to become an Operand when it is added to another Formula.
The best way to do it would be to use an expando object that is filled by each operand using polymorphic dispatch. The expando object lets you add custom properties, and the polymorphic dispatch lets you close your code against operands change.
You would start by using a base class for the Operand that contains your basic elements
public abstract class Operand
{
public int Id { get; set; }
public string Name { get; set; }
public dynamic BuildObject()
{
dynamic o = new ExpandoObject();
o.Id = Id;
o.Name = Name;
AddPropertiesToObject(o);
return o;
}
protected internal abstract void AddPropertiesToObject(dynamic o);
}
Then adding a new Operand type is very easy since you can control what you will add to it independently:
public class Stock : Operand
{
public double StockValue { get; set; }
protected internal override void AddPropertiesToObject(dynamic o)
{
// I decided to ignore the base class Id and Name
// adding them would be trivial, but may not be what you need since
// it would overwrite the base values...
// To add them you would have to wrap this virtual method call with
// a call to a function doing the insertion in the base class
o.StockValue = StockValue;
}
}
The Formula object would simply iterate on the contained operands and call their AddPropertiesToObject in turn (of course it can also add its own data but for the example I didn't include any)
public class Formula : Operand
{
public List<Operand> InnerOperands { get; set; }
protected internal override void AddPropertiesToObject(dynamic o)
{
foreach (var op in InnerOperands)
{
op.AddPropertiesToObject(o);
}
}
}
What I posted here may looks like a lot of code but it's actually very straightforward.
Most of the properties and constructors are there to simplify the script in the main function.
The base concept is to create a Generic Class for the operands that contains a reference to the base Indicator object it's created from.
Test this code in an empty project and it'll be very easy to understand from the output.
class Indicator{
// Common properties
}
class Counter : Indicator{
public int CounterIndex;
public Counter(int cI){
CounterIndex = cI;
}
public void Print()
{
Console.WriteLine("CounterIndex: {0}", CounterIndex);
}
}
class Operand{
// Common operand properties
}
class Operand<T> : Operand{
public T BaseIndicator;
public Operand(T bI){
BaseIndicator = bI;
}
}
class Formula : Indicator{
public string FormulaExpression;
public int FormulaCode;
public List<Operand> OperandsList = new List<Operand>();
public Formula(string fE, int fC){
FormulaExpression = fE;
FormulaCode = fC;
}
public void Print ()
{
Console.WriteLine ("FormulaExpression: {0}; FormulaCode: {1}",
FormulaExpression, FormulaCode);
if (OperandsList.Count == 0) {
return;
}
Console.WriteLine("Begin Operands: ");
foreach(Operand o in OperandsList){
if(o is Operand<Counter>){
Operand<Counter> cO = o as Operand<Counter>;
cO.BaseIndicator.Print();
}else if(o is Operand<Formula>){
Operand<Formula> fO = o as Operand<Formula>;
fO.BaseIndicator.Print();
}else{
// I'ts a simple Indicator
}
}
Console.WriteLine("End Operands");
}
}
class MainClass
{
public static void Main (string[] args)
{
Counter c1 = new Counter(2);
Counter c2 = new Counter(3);
Formula f1 = new Formula("a + b", 7);
Formula f2 = new Formula("a * b", 10);
Formula f = new Formula("a ^ b", 32);
f.OperandsList.Add(new Operand<Counter>(c1));
f.OperandsList.Add(new Operand<Formula>(f1));
f.OperandsList.Add(new Operand<Counter>(c2));
f.OperandsList.Add(new Operand<Formula>(f2));
f.Print();
Console.ReadLine();
}
}
I was having trouble setting properties and realized I could only set the properties within a function or method. My question is why is this the case?
Here is my code that works:
public class SomeClass
{
Car car = new Car();
public Car JustAMethod()
{
Car car = new Car();
car.year = 2012;
return car;
}
}
Why doesn't this work:
public class SomeClass
{
Car car = new Car();
car.year = 2012;//I get an error here
}
The language specification (for the most part) forbids the execution of arbitrary statements at the class level. All that can be done is to specify default values for static or instance members of the class.
All code, generally speaking, must be executed within methods of a class.
As AntLaC mentioned, you can get around this by specifying the value using the object initialization syntax. Since objects can be defined at the class level (as "default values for static or instance members"), using syntax like the below will also work:
public class SomeClass
{
Car car = new Car() {
year = 2012;
};
}
Because that is the way the language specification requires it.
Imagine the mess that would happen if it were possible to write anything anywhere you liked:
We'd have ended up with PHP, and that was certainly not a design goal of C#.
If you want to set specific properties you can try this without being in a method
Car car = new Car()
{
year = 2012
};
The simple answer is that those are just the rules of the language. However, you have a few options:
Create a constructor so that Car takes a year:
public class SomeClass
{
Car car = new Car(2012);
}
Use object initializers:
public class SomeClass
{
Car car = new Car() { Year = 2012 };
}
Use a method:
public class SomeClass
{
Car car = InitializeCar(2012);
private Car InitializeCar(int year)
{
Car car = new Car();
car.Year = 2012;
return car;
}
}
You can't set the property in that way, it isn't allowed. You can do it in a constructor/ in a method/in a property. Or in this way:
public class SomeClass{
Car car = new Car(){ year = 2012 };
}
Or you can pass to the constructor your value:
public class Car{
public int year;
public Car(int year){
this.year = year;
}
}
And:
public class SomeClass{
Car car = new Car(2012);
}
greetings, im am new to programming and at the moment developing a clone of the game battleships. i need to implement a fleet of 5 ships. this is what i have done so far:
class Cell holds the status of a table cell:
public class Cell
{
// class for holding cell status information
public enum cellState
{
WATER,
SCAN,
SHIPUNIT,
SHOT,
HIT
}
public Cell()
{
currentCell = cellState.WATER;
}
public Cell(cellState CellState)
{
currentCell = CellState;
}
public cellState currentCell { get; set; }
}
class GridUnit holds table cell info:
public class GridUnit
{
public GridUnit()
{
Column = 0;
Row = 0;
}
public GridUnit(int column, int row)
{
Column = column;
Row = row;
}
public int Column { get; set; }
public int Row { get; set; }
}
finally class Shipunit contains both the above classes and acts as a wrapper for state info of an individual cell:
public class ShipUnit
{
public GridUnit gridUnit = new GridUnit();
public Cell cell = new Cell(Cell.cellState.SHIPUNIT);
}
at the moment i am thinking about implementing the fleet info in a Jagged Array like this:
ShipUnit[][] Fleet = new ShipUnit[][]
{
new ShipUnit[] {ShipUnit,ShipUnit,ShipUnit,ShipUnit,ShipUnit},
new ShipUnit[] {ShipUnit,ShipUnit,ShipUnit,ShipUnit},
new ShipUnit[] {ShipUnit,ShipUnit,ShipUnit}
new ShipUnit[] {ShipUnit,ShipUnit,ShipUnit}
new ShipUnit[] {ShipUnit,ShipUnit}
};
i realize the last bit of code does not work. it is only for presenting the idea.
but the problem being i need a field that states what type of ship each line of jagged array represent and i dont think it is practical to state this info in every cell information.
so i would like some ideas of implementation of this issue from you.
thank you.
class Ship
{
ShipUnit[] shipUnits;
string type;
public Ship(int length, string type)
{
shipUnits = new ShipUnit[length];
this.type = type;
}
}
Ship[] fleet = new Ship[5];
fleet[0] = new Ship(5, "Carrier");
fleet[1] = new Ship(4, "Battleship");
fleet[2] = new Ship(3, "Submarine");
fleet[3] = new Ship(3, "Something else");
fleet[4] = new Ship(2, "Destroyer");
I think I would define an owning Grid class, the holds all of the GridUnits. Then this Grid would also hold a List. A Ship would just have properties like size, orientation, BowCell. When adding a ship to the grid, the Grid could set the status of the units accordingly.
This way, you can have usefull methods on the ship level like IsSunk(), OccupiesUnit(), etc...
Why don't you create something like this
class Ship
{
public ShipUnits[] _SUParts;
public String _strType;
public Ship(String styType, int NbPart)
{
_SUParts = new ShipUnit[length];
_strType = strType;
}
}
that being said, I would not put all members public. I'de use Getter/Setter to change the values
I assumed by type you also mean the name of the ship (destroyer,etc.)
How many types of ships are there. Is that fixed or variable at runtime?
If it is fixed and not too many, you should probably just use separate arrays for each. If they are variable AND you have only one array for each type, you could use a generic dictionary (of enumShipUnitType, ShipUnit[]).
You can then iterate over the dictionary by getting the KeyValuePair from it like so.
For Each kvp As KeyValuePair(Of enumShipUnitType, ShipUnit[]) In m_dictShipUnits
For each oShipUnit as Shipunit in kvp.Value
'Do whatever
Next
Next
class Ship {
public Size Size { get; set; }
public Orientation Orientation { get; set; }
public Point Position { get; set; }
public Boolean Sunk { get; set; }
public String Name { get; set; }
[...]
}
Inherit from Ship and create sub classes like Battleship, Cruiser, etc for the different ships. Add a "IsHit(Point shot)" method that compares Size, Orientation, Position and the shot position (the Rectangle class has many nice functions for that).
class Grid {
private Size size = new Size(10, 10);
private List<Ship> ships = new List<Ship>();
private List<Point> shots;
[...]
}
Create two grids (one for each player), add a shoot method that calls IsHit for every Ship and then adds the shot to shots. After each move if every point of a ship is hit (is in shots) and set the ship to Sunk if all are hit.