Auto increment ID C# - c#

I am busy with a really small console application for c#. I am just new into c# and i'm only familiar with Java. My school gave the assignment to create a console application that simulates a car dealer. I already wrote a bunch of code to add cars by console. Things like brand and type and max speed are already implemented. The only thing i still need to realize is the auto creation and incremental of an ID for a car. It has the be unique of course.
My first approach was making the id field static and increment it in the constructor so that each time the object gets created the id gets ++;
I saw allot of people on stackoverflow doing allot of things but the solutions did not work or the where to big.
This is my code;
class Car : Vehicle
{
public string brand { get; set; }
public string type { get; set; }
public int maxSpeed { get; set; }
public double price { get; set; }
public static int carID { get; set; }
public Car(string _brand, string _type, int _maxspeed, double _price)
{
this.brand = _brand;
this.type = _type;
this.maxSpeed = _maxspeed;
this.price = _price;
this.carID++;
}
}
I added 3 cars to my list but the result is that all cars have ID 3;
Maybe someone could help me, thanks in advance.

class Car : Vehicle
{
public string brand { get; set; }
public string type { get; set; }
public int maxSpeed { get; set; }
public double price { get; set; }
public int carID { get; private set; }
public static int globalCarID;
public Car(string _brand, string _type, int _maxspeed, double _price)
{
this.brand = _brand;
this.type = _type;
this.maxSpeed = _maxspeed;
this.price = _price;
this.carID = Interlocked.Increment(ref globalCarID);
}
}
This maintains a global ID counter, and increments it atomically to make it thread-safe.
Note that the first ID assigned this way would be 1. You can initialize globalCarID with -1 to start at 0.

Just to remove static and add lock section for avoiding duplicate of Ids
class Car : Vehicle
{
private static object sync = new object();
private static int _globalCount;
public string brand { get; set; }
public string type { get; set; }
public int maxSpeed { get; set; }
public double price { get; set; }
public int carID { get; set; }
public Car(string _brand, string _type, int _maxspeed, double _price)
{
this.brand = _brand;
this.type = _type;
this.maxSpeed = _maxspeed;
this.price = _price;
lock (sync)
{
this.carID = ++globalCount;
}
}
}

A static variable is shared between all instances of the class.
Incrementing it in the constructor makes all instances of that class 'see' the last value assigned to the static variable.
You should create a normal instance carID variable (not static) and use a protected static variable defined in the base class to grab the current value at constructor time, assign to your carID instance variable and then increment the base class value.
class Vehicle
{
protected static int FakeID = 1;
}
class Car : Vehicle
{
public string brand { get; set; }
public string type { get; set; }
public int maxSpeed { get; set; }
public double price { get; set; }
public int carID { get; set; }
public Car(string _brand, string _type, int _maxspeed, double _price)
{
this.brand = _brand;
this.type = _type;
this.maxSpeed = _maxspeed;
this.price = _price;
this.carID = base.FakeID++;;
}
}
void Main()
{
Car a = new Car("xyz", "Auto", 120, 12000);
Car b = new Car("kwx", "Moto", 180, 8000);
Console.WriteLine(a.carID);
Console.WriteLine(b.carID);
}
Keep in mind that this will work correctly if your code doesn't use multithreaded access to the constructor. In case of multithreading you need to look at Interlocked.Increment

Related

How to get property value of object which is in object array from another class

I want to get property value of an object which is in object array from another class. I tried to use reflection, but I had to do something wrong...
My code:
//Map.cs
//in BoardTiles i keep objects of classes which have property "Name" and I want to get it.
public class Map
{
public int Rows { get; private set; }
private int Cols { get; set; }
public Object[,] BoardTiles { get; private set; }
private Floor Floor { get; set; }
private PlayerTile PlayerTile { get; set; }
private Sword OldSword { get; set; }
public Map()
{
this.Rows = 10;
this.Cols = 40;
this.BoardTiles = new Object[Rows, Cols];
this.Floor = new Floor();
this.PlayerTile = new PlayerTile();
this.OldSword = new Sword("oldSword", 5);
}
//Sword.cs
//this is what the sword class looks like, object of this class is stored in BoardTiles
{
public class Sword : Tile
{
public override string Type { get; set; }
public string Name { get; set; }
public int Dmg { get; set; }
public Sword(string name, int dmg)
{
this.Type = "sword";
this.Name = name;
this.Dmg = dmg;
}
}
}
//Program.cs
case ConsoleKey.Spacebar:
Console.Clear();
map.getItem(playerPositionX, playerPositionY);
/* map.movefill(playerPositionX, playerPositionY);
*/ map.printBoard();
Console.Write(map.BoardTiles[playerPositionX, playerPositionY]);
**//Place where i need value of property of object from array of objects**
break;
}
}
I'm doing a dungeon crawler and when the player steps over a tile with an item he can pick the item, so the situation is - player is on the item tile which is an index in an array of objects and I want to know the name of this object. 

Create object - product with name and price - best practice C#

The program should create a car which can have many parts and be able to set a part which always has a corresponding price to it.
My current car and part classes:
public class Car
{
public Car(string brand, string windshieldType, List<AdditionalCarParts> additionalCarParts) {
Brand = brand;
WindshieldType = windshieldType;
AdditionalCarParts = additionalCarParts;
}
public string Brand { get; set; }
public string WindshieldType { get; set; }
public int Price { get; set; }
public List<AdditionalCarParts> AdditionalCarParts { get; set; }
}
public class AdditionalCarParts
{
public AdditionalCarParts(PartData.PartNames part, int price) {
Part = part;
Price = price;
}
public PartData.PartNames Part { get; set; }
public int Price { get; set; }
}
public class PartData
{
public enum PartNames
{
EngineHeater,
SteeringWheelHeater,
HeadsUpDisplay,
Turbo
}
public static int EngineHeaterPrice() => 3000;
public static int SteeringWheelHeaterPrice() => 800;
public static int HeadsUpDisplayPrice() => 1200;
public static int TurboPrice() => 5000;
}
}
How to add one part to list of parts in my car, and that part has a price on it, for example:
var part = new AdditionalCarParts(PartData.PartNames.Turbo) and an object is created with price of 5000 set on it.
Should there even be a list of parts, or are there any better practices for this?
Thanks.
I would not use a class to hold the prices. I would use a data structure as a Dictionary to hold that info.
public class AdditionalCarParts
{
public AdditionalCarParts(PartData.PartNames part, int price) {
Part = part;
//Price = price;
}
public enum PartNames
{
EngineHeater,
SteeringWheelHeater,
HeadsUpDisplay,
Turbo
}
private Dictionary<PartNames, int> prices = new Dictionary<PartNames, int>() {
{ PartNames.EngineHeater, 3000 },
{ PartNames.SteeringWheelHeater, 800 },
{ PartNames.HeadsUpDisplay, 1200 },
{ PartNames.Turbo, 5000 },
};
public PartNames Part { get; set; }
public int Price(PartNames name) => prices[name];
}
"How to add one part to list of parts in my car" -> I find that adding it to the list is fine. As the prices are already pre-defined you would not need to provide the price in the class constructor.
If prices can change, you can handle that with a SetPrice method to update the dictionary. I would do:
public void SetPrice(PartNames name, int price) {
prices[name] = price;
}

C# - calling override method

I am new to C# so please excuse gaps in my knowledge. In my code I have TWO types of foods Fresh and Regular.
When determining cost Fresh items use different FindCost method than Regular.
I am having trouble working out how to call the FindCost() method for Fresh Items.
I think i need to use the base keyword somehow s:
namespace Groceries
{
class Program
{
static void Main(string[] args)
{
PurchasedItem CheckoutItem4 = new FreshItem();
CheckoutItem4.Name = "Rump Steak";
CheckoutItem4.Condition = "Fresh";
CheckoutItem4.Price = 11.99;
CheckoutItem4.Weight = .8;
ArrayList invoiceArray = new ArrayList();
invoiceArray.Add(CheckoutItem1);
foreach (PurchasedItem checkoutItem in invoiceArray)
{
Console.WriteLine($"Quantity: {checkoutItem.Quantity} Weight: {checkoutItem.Weight}kg ");
}
Console.ReadLine();
}
}
public class GroceryItem
{
public string Name { get; set; }
public string Condition { get; set; }
public double Price { get; set; }
public GroceryItem()
{
}
public GroceryItem(string name, double price)
{
this.Name = name;
this.Price = price;
}
public static void Invoice()
{
Console.WriteLine();
}
}
public class PurchasedItem : GroceryItem
{
public int Quantity { get; set; }
public double Weight { get; internal set; }
public virtual double FindCost()
{
double cost = Quantity * Price * 1.1; //1.1 is GST
return cost;
}
}
public class FreshItem : PurchasedItem
{
public new double Weight { get; set; } //kg
public override double FindCost()
{
double cost = Weight * Price;
return cost;
}
}
}
any help appreciated
When you set Weight with the reference of type PurchasedItem :
CheckoutItem4.Weight = .8;
You set the field Weight declared in class PurchasedItem, but the method FindCost use the field Weight defined in class FreshItem that is not initialised. So, just remove de line : public new double Weight { get; set; } //kg. You do not need to redefine this field.
Your current code is correctly calling the right FindCost() method, but you've defined your classes in a poor way, and hiding with the new keyword can make it call the wrong method.
You should make GroceryItem abstract and have both of your classes directly inherit from this. Then GroceryItem can has an abstract FindCost() method. Also, if you're hiding a method with new then you're probably doing something wrong. You should find that this eliminates all uncertainty when calling FindCost().
Also, you should use decimal rather than double for financial calculations as double doesn't always accurately represent monetary values.
Here are the improved classes:
void Main()
{
List<GroceryItem> invoiceArray = new List<GroceryItem>()
{
new FreshItem() { Name = "Rump Steak", Price = 11.99m, Weight = 0.8 },
new PurchasedItem() { Name = "Cream", Price = 2.2m, Quantity = 1, Weight = 0.6 },
};
foreach (GroceryItem checkoutItem in invoiceArray)
{
if (checkoutItem is PurchasedItem purchasedItem)
{
Console.WriteLine($"Condition: {checkoutItem.Condition}; Quantity: {purchasedItem.Quantity}; Weight: {checkoutItem.Weight}kg");
}
else
{
Console.WriteLine($"Condition: {checkoutItem.Condition}; Weight: {checkoutItem.Weight}kg");
}
}
Console.ReadLine();
}
public abstract class GroceryItem
{
public string Name { get; set; }
public abstract string Condition { get; }
public double Weight { get; set; }
public decimal Price { get; set; }
public GroceryItem() { }
public GroceryItem(string name, decimal price)
{
this.Name = name;
this.Price = price;
}
public abstract decimal FindCost();
}
public class PurchasedItem : GroceryItem
{
public int Quantity { get; set; }
public override string Condition { get { return "Regular"; } }
public override decimal FindCost()
{
decimal cost = Quantity * Price * 1.1m; //1.1m is GST
return cost;
}
}
public class FreshItem : GroceryItem
{
public override string Condition { get { return "Fresh"; } }
public override decimal FindCost()
{
decimal cost = (decimal)Weight * Price;
return cost;
}
}

How do I correctly add mixes of different interfaces to different classes in C#?

I am trying to develop an API for some assessment software that will allow me to create questions consisting of the question text, multiple choice text and the choice index of the correct answer.
All questions are worth 10 points and the question can only be answered once.
For QuestionTypeA however, the user can change the number of retries and QuestionTypeB, the user can change both the number of retries and the score.
The reason for the CommonFunctions interface is so that I don't have to duplicate QuestionText, AddChoice and SetAnswer in each of the QuestionType interfaces.
But this does then leave me with empty interfaces, which I am not sure is correct?
Also, to instantiate an object I have to write
QuestionTypeA QTA = (QuestionTypeA)new Question();
I would rather the Question class dealt with the cast so that the user can then just type:
QuestionTypeA QTA = new Question();
How can achieve this?
Thanks
Andrew
public interface IRetryable
{
int Retries { set; get; }
}
public interface IScoreable
{
int Score { set; get; }
}
public interface CommmonFunctions
{
string QuestionText { set; get; }
void AddChoice(string ChoiceText);
int SetAnswer { set; get; }
}
public interface QuestionTypeA : CommmonFunctions, IRetryable
{
}
public interface QuestionTypeB : CommmonFunctions, IRetryable, IScoreable
{
}
public interface QuestionTypeC : CommmonFunctions
{
}
class Question : CommmonFunctions
{
private List<string> Choices;
public Question()
{
Choices = new List<string>();
Retries = 1;
Score = 10;
}
public string QuestionText { set; get; }
public void AddChoice(string ChoiceText)
{
Choices.Add(ChoiceText);
}
public int SetAnswer { set; get; }
public int Retries { set; get; }
public int Score { set; get; }
}
It seems you are over-thinking things...
Just keep it simple.
var question1 = new QuestionTypeA();
var question2 = new QuestionTypeB();
public interface IRetryable
{
int Retries { set; get; }
}
public interface IScoreable
{
int Score { set; get; }
}
public abstract class Question
{
private List<string> choices = new List<string>();
public string QuestionText { set; get; }
public int SetAnswer { set; get; }
public void AddChoice(string choiceText)
{
choices.Add(choiceText);
}
}
public class QuestionTypeA : Question, IRetryable
{
public QuestionTypeA()
{
Retries = 1;
}
public int Retries { set; get; }
}
public class QuestionTypeB : Question, IScoreable
{
public QuestionTypeB()
{
Score = 0;
}
public int Score { set; get; }
}
Thanks ASh for your response.
I guess it would make sense to incorporate in them in to the interface.
I now need to add another interface (IShuffle) to QuestionTypeA as below.
interface IShuffable
{
void Shuffle();
}
public class QuestionTypeA : Question, IRetryable, IShuffable
{
public QuestionTypeA()
{
Retries = 1;
}
public int Retries { set; get; }
public void Shuffle()
{
// Code to implement shuffling the choices
}
}
Shuffle has nothing to do with QuestionType B or C, so Ideally I would like to hide this method from instances of QuestionType B and C so that it doesn't appear in intellisense.
Any attempt to call the shuffle method on instances of either QuestionTypeB or C, should then result in a standard compiler error i.e "QuestionTypeB does not contain a definition for shuffle ...".
Would it be better to use interfaces for this solution given the above? or something else?
Thanks Andrew
since all question have at least score 10 and 0 or more retries, why not include that info in the common interface like this?
public interface CommmonFunctions
{
string QuestionText { set; get; }
void AddChoice(string ChoiceText);
int SetAnswer { set; get; }
int Score { set; get; }
bool ScoreReadonly {get;}
int Retries { set; get; }
bool RetriesReadonly {get;}
}
ScoreReadonly and RetriesReadonly show if score or retries count can be changed outside class:
class Question : CommmonFunctions
{
private List<string> Choices;
public Question()
{
Choices = new List<string>();
_retries = 1;
_score = 10;
}
public string QuestionText { set; get; }
public void AddChoice(string ChoiceText)
{
Choices.Add(ChoiceText);
}
public int SetAnswer { set; get; }
private int _retries;
public int Retries
{
get{ return _retries; }
set
{
if (!RetriesReadonly)
_retries = value;
}
}
private int _score;
public int Score
{
get{ return _score; }
set
{
if (!ScoreReadonly)
_score = value;
}
}
public virtual bool ScoreReadonly {get{return false;}}
public virtual bool RetriesReadonly {get{return false;}}
}
UPDATE
public interface IShuffable
{
void Shuffle();
}
class QuestionTypeA : Question, IShuffable
{
// question of type A can't change score
public override bool ScoreReadonly { get {return true;}}
public void Shuffle()
{
// Code to implement shuffling the choices
}
}
class QuestionTypeB : Question {}

How to get difference properties of object in c#?

i have a class with some properties like this:
public class Car
{
public long No { get; set; }
public string Name { get; set; }
public int Door { get; set; }
public Color Color { get; set; }
public int MaxSpeed { get; set; }
public int Price { get; set; }
}
(this class is an example, my real class is very bigger than it.)
In my program, I need to get difference properties of this class from db(not all properties each time). For example in one case I need name and color of some cars, and in other case I need name and door and price.
I want to create one method that support all difference conditions. I know that i could create it using ‘params’ and ‘enum’, but I am research about best way to do it. Thanks
You can just query the propertie when it is called.
public int Value{
get{
int myValue = getValue();
return myValue;
}
}
Try do this way:
public object[] GetProperties(int state)
{
object[] temp;
switch(state)
{
case(0):
{
temp=new object[]{Name,Color};
}break;
case(1):
{
temp=new object[]{Name,door};
}
}
}
After that, you know , what need return your function, and it's easy parse return result!

Categories