Sorting array in ascending order error - c#

My code below works fine but what I want to do is to display the summary in ascending order according to its OrderNum. I tried to put Array.Sort(order[x].OrderNum) but error cannot convert from int to System.Array. Any suggestions on how I can sort this? Thank you very much!
using System;
class ShippedOrder
{
public static void Main()
{
Order[] order = new Order[5];
int x, y;
double grandTotal = 0;
bool goodNum;
for (x = 0; x < order.Length; ++x)
{
order[x] = new Order();
Console.Write("Enter order number: ");
order[x].OrderNum = Convert.ToInt32(Console.ReadLine());
goodNum = true;
for (y = 0; y < x; ++y)
{
if (order[x].Equals(order[y]))
goodNum = false;
}
while (!goodNum)
{
Console.Write("Sorry, the order number " + order[x].OrderNum + " is a duplicate. " + "\nPlease re-enter: ");
order[x].OrderNum = Convert.ToInt32(Console.ReadLine());
goodNum = true;
for (y = 0; y > x; ++y)
{
if (order[x].Equals(order[y]))
goodNum = false;
}
}
Console.Write("Enter customer name: ");
order[x].Customer = Console.ReadLine();
Console.Write("Enter Quantity: ");
order[x].Quantity = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("\nSummary:\n");
for (x = 0; x < order.Length; ++x)
{
Array.Sort(order[x].OrderNum); //This line is where the error is located
Console.WriteLine(order[x].ToString());
grandTotal += order[x].Total;
}
Console.WriteLine("\nTotal for all orders is Php" + grandTotal.ToString("0.00"));
Console.Read();
}
public class Order
{
public int orderNum;
public string cusName;
public int quantity;
public double total;
public const double ItemPrice = 19.95;
public Order() { }
public Order(int ordNum, string cusName, int numOrdered)
{
OrderNum = ordNum;
Customer = cusName;
Quantity = numOrdered;
}
public int OrderNum
{
get { return orderNum; }
set { orderNum = value; }
}
public string Customer
{
get { return cusName; }
set { cusName = value; }
}
public int Quantity
{
get
{
return quantity;
}
set
{
quantity = value;
total = quantity * ItemPrice + 4;
}
}
public double Total
{
get
{
return total;
}
}
public override string ToString()
{
return ("ShippedOrder " + OrderNum + " " + Customer + " " + Quantity +
" #Php" + ItemPrice.ToString("0.00") + " each. " + "Shipping is Php4.00\n" + " The total is Php" + Total.ToString("0.00"));
}
public override bool Equals(Object e)
{
bool equal;
Order temp = (Order)e;
if (OrderNum == temp.OrderNum)
equal = true;
else
equal = false;
return equal;
}
public override int GetHashCode()
{
return OrderNum;
}
}
}

Just use Linq:
order = order.OrderBy(x => x.OrderNum).ToArray();

While looking this link, found that Array.Sort will not take integer as parameter.
You have to pass all the data as Array object.

Try the following:
order.Sort( delegate (Order o1, Order o2) {
return o1.OrderNum.CompareTo(o2.OrderNum);
});

Related

does not contain a constructor

Type definitions
using System;
public enum Direction { Right, Left, Forward };
class Chaharpa
{
private int age;
private int height;
private int cordinates_x;
private int cordinates_y;
public Chaharpa(int a, int b, int x, int y)
{
age = a;
height = b;
cordinates_x = x;
cordinates_y = y;
}
public Chaharpa(int c, int d)
{
age = c;
height = d;
cordinates_x = 0;
cordinates_y = 0;
}
public int Age
{
get { return age; }
}
public int Height
{
get { return height; }
}
public int Cordinates_x
{
get { return cordinates_x; }
set { cordinates_x = value; }
}
public int Cordinates_y
{
get { return cordinates_y; }
set { if (value > 0) cordinates_y = value; }
}
public void Move(Direction direction)
{
if (direction == Direction.Forward)
Cordinates_y++;
else if (direction == Direction.Right)
Cordinates_x++;
else if (direction == Direction.Left)
Cordinates_x--;
}
class horse : Chaharpa
{
public bool is_wild;
public void Jump(int x)
{
x = Cordinates_y;
Cordinates_y += 5;
}
public void Print()
{
Console.WriteLine("Horse Information: Age," + Age + ", Height: " + Height + ", Wild: " + is_wild + ", X: " + Cordinates_x + ", Y: " + Cordinates_y);
}
}
}
Usage
class Program
{
static void Main(string[] args)
{
int age, x, y, minAge = 0;
int height;
bool wild;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Horse #" + (i + 1));
Console.Write("Enter Age: ");
age = int.Parse(Console.ReadLine());
Console.Write("Enter Height: ");
height = int.Parse(Console.ReadLine());
Console.Write("Enter X: ");
x = int.Parse(Console.ReadLine());
Console.Write("Enter Y: ");
y = int.Parse(Console.ReadLine());
Console.Write("Is Wild: ");
wild = bool.Parse(Console.ReadLine());
minAge = age;
if (minAge > age)
{
minAge = age;
}
}
Console.WriteLine();
horse ob = new horse();
ob.Jump(minAge);
ob.move();
ob.Print();
Console.ReadKey();
}
}
I get these errors in Visual Studio:
'Chaharpa' does not contain a constructor that takes 0 arguments
The type or namespace name 'horse' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'horse' could not be found (are you missing a using directive or an assembly reference?)
In the class Chaharpa you defined two constructors, both take arguments.
Creating your own constructor overrides the default constructor.
Usually, when inheriting from a base class you want to initialize the inheriting class with parameters that are used to initialize the base class, look more at this thread.
The horse class inside Chaharpa and Chaharpaclass are not public.
Changing classes horse and Chaharpa to public and accessing it as:
Chaharpa.horse ob = new Chaharpa.horse();
is the right way to go.
Here are some mitigations to the code:
using System;
using System.ComponentModel;
public enum Direction
{ Right, Left, Forward };
public class Chaharpa
{
private int age;
private int height;
private int cordinates_x;
private int cordinates_y;
public Chaharpa()
{
}
public Chaharpa(int a, int b, int x, int y)
{
age = a;
height = b;
cordinates_x = x;
cordinates_y = y;
}
public Chaharpa(int c, int d)
{
age = c;
height = d;
cordinates_x = 0;
cordinates_y = 0;
}
public int Age
{
get { return age; }
}
public int Height
{
get { return height; }
}
public int Cordinates_x
{
get { return cordinates_x; }
set { cordinates_x = value; }
}
public int Cordinates_y
{
get { return cordinates_y; }
set { if (value > 0) cordinates_y = value; }
}
public void Move(Direction direction)
{
if (direction == Direction.Forward)
Cordinates_y++;
else if (direction == Direction.Right)
Cordinates_x++;
else if (direction == Direction.Left)
Cordinates_x--;
}
public class horse : Chaharpa
{
public bool is_wild;
public void Jump(int x)
{
x = Cordinates_y;
Cordinates_y += 5;
}
public void move()
{
throw new NotImplementedException();
}
public void Print()
{
Console.WriteLine("Horse Information: Age," + Age + ", Height: " + Height + ", Wild: " + is_wild + ", X: " + Cordinates_x + ", Y: " + Cordinates_y);
}
}
}
class Program
{
static void Main(string[] args)
{
int age, x, y, minAge = 0;
int height;
bool wild;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Horse #" + (i + 1));
Console.Write("Enter Age: ");
age = int.Parse(Console.ReadLine());
Console.Write("Enter Height: ");
height = int.Parse(Console.ReadLine());
Console.Write("Enter X: ");
x = int.Parse(Console.ReadLine());
Console.Write("Enter Y: ");
y = int.Parse(Console.ReadLine());
Console.Write("Is Wild: ");
wild = bool.Parse(Console.ReadLine());
minAge = age;
if (minAge > age)
{
minAge = age;
}
}
Console.WriteLine();
Chaharpa.horse ob = new Chaharpa.horse();
ob.Jump(minAge);
// You can call the Move defined in Chaharpa
ob.Move(<PASS DIRECTION PARAMETER HERE>);
ob.Print();
Console.ReadKey();
}
}
First, you have to study more about object creation in C#. When creating an object of a child class inside the child class constructor, it's calling the base class constructor.
using System;
public class Program
{
public static void Main()
{
Child child = new Child();
}
}
public class Parent{
public Parent(){
Console.WriteLine("I am parent");
}
}
public class Child : Parent {
public Child(){
Console.WriteLine("I am child");
}
}
Output
I am parent
I am child
When you creating a class there is a default constructor (the constructor which takes 0 arguments). But when you create another constructor (which takes more than 0 arguments) default constructor will replaced by that. You have to manually create default constructor. So at the runtime, it's trying to call the default constructor of the base class constructor. But since it's gone this error occurs.
'Chaharpa' does not contain a constructor that takes 0 arguments
Then you have to study about nested classes in C#.
You can't just call inner class by it's name. You have to reference it from the outer class.
using System;
public class Program
{
public static void Main()
{
Outer.Inner child = new Outer.Inner();
}
}
public class Outer{
public Outer(){
Console.WriteLine("I am outer");
}
public class Inner : Outer {
public Inner(){
Console.WriteLine("I am inner");
}
}
}
Output
I am outer
I am inner
That's why you get the error The type or namespace name 'horse' could not be found (are you missing a using directive or an assembly reference?)
This code will work.
using System;
public enum Direction
{ Right, Left,Forward};
class Chaharpa
{
private int age;
private int height;
private int cordinates_x;
private int cordinates_y;
public Chaharpa(){}
public Chaharpa(int a, int b, int x, int y)
{
age = a;
height = b;
cordinates_x = x;
cordinates_y = y;
}
public Chaharpa(int c, int d)
{
age = c;
height = d;
cordinates_x = 0;
cordinates_y = 0;
}
public int Age
{
get{ return age; }
}
public int Height
{
get{ return height;}
}
public int Cordinates_x
{
get{ return cordinates_x;}
set{ cordinates_x = value;}
}
public int Cordinates_y
{
get{return cordinates_y;}
set{ if (value > 0)cordinates_y = value;}
}
public void Move(Direction direction)
{
if (direction == Direction.Forward)
Cordinates_y++;
else if (direction == Direction.Right)
Cordinates_x++;
else if (direction == Direction.Left)
Cordinates_x--;
}
public class horse : Chaharpa
{
public bool is_wild;
public void Jump(int x)
{
x = Cordinates_y;
Cordinates_y += 5;
}
public void Print()
{
Console.WriteLine("Horse Information: Age," + Age + ", Height: " + Height + ", Wild: " + is_wild + ", X: " + Cordinates_x + ", Y: " + Cordinates_y);
}
}
}
public class Program
{
public static void Main(string[] args)
{
int age, x, y, minAge = 0;
int height;
bool wild;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Horse #" + (i + 1));
Console.Write("Enter Age: ");
age = int.Parse(Console.ReadLine());
Console.Write("Enter Height: ");
height = int.Parse(Console.ReadLine());
Console.Write("Enter X: ");
x = int.Parse(Console.ReadLine());
Console.Write("Enter Y: ");
y = int.Parse(Console.ReadLine());
Console.Write("Is Wild: ");
wild = bool.Parse(Console.ReadLine());
minAge = age;
if (minAge > age)
{
minAge = age;
}
}
Console.WriteLine();
Chaharpa.horse ob = new Chaharpa.horse();
ob.Jump(minAge);
ob.Print();
}
}
Use one file for one class is a good practice.

C# - Difficulty with method involving array

I am creating a program that intakes info for the number of visits on separate days to a centre. I am using an array to keep track of that info, but I also need to create a method that calls up the day with the least number of visits and then displays it in an output.
class ScienceCentreVisitation
{
private string centreName;
private string city;
private decimal ticketPrice;
private string[] visitDate;
private int[] adultVisitors;
private decimal[] totalRevenue;
//constructors
public ScienceCentreVisitation()
{
}
public ScienceCentreVisitation(string cent)
{
centreName = cent;
}
public ScienceCentreVisitation(string cent, string cit, decimal price, string[] date, int[] visit, decimal[] rev)
{
visitDate = new string[date.Length];
adultVisitors = new int[visit.Length];
totalRevenue = new decimal[rev.Length];
Array.Copy(date, 0, visitDate, 0, date.Length);
Array.Copy(visit, 0, adultVisitors, 0, adultVisitors.Length);
Array.Copy(rev, 0, totalRevenue, 0, rev.Length);
centreName = cent;
city = cit;
ticketPrice = price;
}
//properties
public string CentreName
{
get
{
return centreName;
}
set
{
centreName = value;
}
}
public string City
{
get
{
return city;
}
set
{
city = value;
}
}
public decimal TicketPrice
{
get
{
return ticketPrice;
}
set
{
ticketPrice = value;
}
}
public string[] VisitDate
{
get
{
return visitDate;
}
set
{
visitDate = value;
}
}
public int[] AdultVisitors
{
get
{
return adultVisitors;
}
set
{
adultVisitors = value;
}
}
public decimal[] TotalRevenue
{
get
{
return totalRevenue;
}
set
{
totalRevenue = value;
}
}
//methods
public decimal CalculateTotalRevenue()
{
decimal totalRev;
int cntOfValidEntries;
int total = 0;
foreach (int c in adultVisitors)
total += c;
cntOfValidEntries = TestForZeros();
totalRev = (decimal)total / cntOfValidEntries;
return totalRev;
}
public int TestForZeros()
{
int numberOfTrueVisits = 0;
foreach (int cnt in adultVisitors)
if (cnt != 0)
numberOfTrueVisits++;
return numberOfTrueVisits;
}
public int GetIndexOfLeastVisited()
{
int minVisIndex = 0;
for (int i = 1; i < adultVisitors.Length; i++)
if (adultVisitors[i] < adultVisitors[minVisIndex])
minVisIndex = i;
return minVisIndex;
}
public int GetLeastVisited()
{
return adultVisitors[GetIndexOfLeastVisited()];
}
public string GetDateWithLeastVisited()
{
return visitDate[GetIndexOfLeastVisited()];
}
public int GetIndexOfMostRevenue()
{
int maxRevIndex = 0;
for (int i = 1; i < totalRevenue.Length; i++)
if (totalRevenue[i] > totalRevenue[maxRevIndex])
maxRevIndex = i;
return maxRevIndex;
}
public decimal GetMostRevenue()
{
return totalRevenue[GetIndexOfMostRevenue()];
}
public string GetDateWithMostRevenue()
{
return visitDate[GetIndexOfMostRevenue()];
}
public override string ToString()
{
return "Name of Centre: " + centreName +
"\nCity: " + city +
"\n Price of ticket: " + ticketPrice +
"\nDate of Least One-Day Adult Visitors:\t\t" + GetDateWithLeastVisited() +
"\nNumber of Least One-Day Adult Visitors:\t\t" + GetLeastVisited() +
"\nDate of Most Total Revenue Collected:\t\t" + GetDateWithMostRevenue() +
"\nHighest Total Revenue Collected:\t\t" + GetMostRevenue();
}
}
Other class:
class ScienceCentreApp
{
static void Main(string[] args)
{
string centreName;
string city;
decimal ticketPrice = 0;
int visitorCnt;
string[] dArray = new String[5];
int[] adultVisitors = new int[5];
decimal[] totalRevenue = new decimal[5];
char enterMoreData = 'Y';
ScienceCentreVisitation scv;
do
{
visitorCnt = GetData(out centreName, out city, out ticketPrice, dArray, adultVisitors, totalRevenue);
scv = new ScienceCentreVisitation(centreName, city, ticketPrice, dArray, adultVisitors, totalRevenue);
Console.Clear();
Console.WriteLine(scv);
Console.Write("\n\n\n\nDo you want to enter more data - " +
"(Enter y or n)? ");
if (char.TryParse(Console.ReadLine(), out enterMoreData) == false)
Console.WriteLine("Invalid data entered - " +
"No recorded for your respones");
} while (enterMoreData == 'y' || enterMoreData == 'y');
Console.ReadKey();
}
public static int GetData(out string centreName, out string city, out decimal ticketPrice, string[] dArray, int[] adultVisitors, decimal[] totalRevenue)
{
int i,
loopCnt;
Console.Clear();
Console.Write("Name of Centre: ");
centreName = Console.ReadLine();
Console.Write("City: ");
city = Console.ReadLine();
Console.Write("Ticket Price: ");
string inValue = Console.ReadLine();
ticketPrice = Convert.ToDecimal(inValue);
Console.Write("How many records for {0}? ", centreName);
string inValue1 = Console.ReadLine();
if (int.TryParse(inValue1, out loopCnt) == false)
Console.WriteLine("Invalid data entered - " +
"0 recorded for number of records");
for (i = 0; i < loopCnt; i++)
{
Console.Write("\nDate (mm/dd/yyyy): ");
dArray[i] = Console.ReadLine();
if (dArray[i] == "")
{
Console.WriteLine("No date entered - " +
"Unknown recorded for visits");
dArray[i] = "Unknown";
}
Console.Write("Number of One-Day Adult Visitors: ");
inValue1 = Console.ReadLine();
if (int.TryParse(inValue1, out adultVisitors[i]) == false)
Console.WriteLine("Invalid data entered - " +
"0 recorded for adults visited");
}
return i;
}
}
I had it working before I made some changes to my program, but now it keeps coming up blank when I run it. Any idea why?
Without having the complete code it's difficult to debug this for you.
But here's a suggestion that came up when I was reading the start of your question:
It seems like the basic gist would be to use a Dictionary<DateTime, int> which would store the number of visits for each day.
Then you can use a simple LINQ query to get the smallest value:
dictionary.OrderBy(kvp => kvp.Value).First()
Of course, you can use a complex class in place of the int and store more data (location, price of admission for that day, adult visits, etc.).
class CenterVisitations
{
internal int Visitations { get; set; }
internal decimal TicketPrice { get; set; }
internal string Location { get; set; }
//add other stuff here, possibly create another class
//to store TicketPrice, Location and other static center data
//and create a reference to that here, instead of the above
//TicketPrice and Location...
}
Then you can define your dictionary like so:
Dictionary<DateTime, CenterVisitations>
And query it almost the same was as last time:
dictionary.Order(kvp => kvp.Value.Visitations).First();
Sorting and selecting would work the same way. Additionally you could add a .Where query to set a range of dates which you want to check:
dictionary.Where(kvp => kvp.Key < DateTime.Today && kvp.Key > DateTime.Today.AddDays(-7)) will only look for the last weeks worth of data.
It also seems you're keeping your data in separate arrays, which means querying it is that much harder. Finally, consider converting dates into DateTime objects rather than strings.

Checking array for duplicate objects - Equals() or Method?

I am learning C# on my own and am stuck on an exercise. I need to ensure that no duplicate OrderNumbers are entered into my order array. I think the idea of the exercise was to use Equals() however, I could not figure out how to get it to work. I haven't learned anything too fancy yet. Would Equals() be better than using a method for this? Also, I am not sure how to call the method so I see the true or false values. If a duplicate is found, it should loop and ask user to re-enter. Thanking you in advance as I am really frustrated... I so need a mentor!
class Program
{
static void Main()
{
Order[] order = new Order[3];
int orderNumber; // hold temp value until object is created
string customerName;
int qtyOrdered;
for (int x = 0; x < order.Length; ++x) //to fill array
{
Console.Write("Enter Order Number: ");
int.TryParse(Console.ReadLine(), out orderNumber); // put order number in temp
if (order[x] != null)
{
if (IsOrderNumberInUse(orderNumber, order) == true)
{
Console.WriteLine("Duplicate order number");
}
}
GetData(out customerName, out qtyOrdered);
order[x] = new Order(orderNumber, customerName, qtyOrdered);
}
Console.ReadLine();
}
//METHOD TO CHECK FOR DUPLICATES
private static bool IsOrderNumberInUse(int orderNumber, Order[] orders)
{
foreach (Order order in orders)
{
if (order.OrderNumber == orderNumber)
{
return true;
}
}
// If orderNumber was not found
return false;
}
static void GetData(out string customerName, out int qtyOrdered)
{
//Console.Write("Enter Order Number: ");
//int.TryParse(Console.ReadLine(), out orderNumber);
Console.Write("Enter Customer Name: ");
customerName = Console.ReadLine();
Console.Write("Enter Quantity Ordered: ");
int.TryParse(Console.ReadLine(), out qtyOrdered);
}
class Order
{
private const double PRICE = 19.95;
public int OrderNumber { get; set; }
public string CustomerName { get; set; }
public int QtyOrdered { get; set; }
public double totalPrice
{
get
{
return QtyOrdered * PRICE;
}
}
public Order(int orderNumber, string customer, int qty) // Constructor
{
OrderNumber = orderNumber;
CustomerName = customer;
QtyOrdered = qty;
}
public override string ToString()
{
return ("\n" + GetType() + "\nCustomer: " + CustomerName + "\nOrder Number: " + OrderNumber +
"\nQuantity: " + QtyOrdered + "\nTotal Order: " + totalPrice.ToString("C2"));
}
public override bool Equals(object x)
{
bool isEqual;
if (this.GetType() != x.GetType())
isEqual = false;
else
{
Order temp = (Order)x;
if (OrderNumber == temp.OrderNumber)
isEqual = true;
else
isEqual = false;
}
return isEqual;
}
public override int GetHashCode()
{
return OrderNumber;
}
}
}
I am trying not to use Lists as I have learned them yet and my next two exercises are connected to this one. I'm afraid if I use Lists, I will be even more lost. I am getting null errors and need help fixing them. Here is my code. Would using Equals be a better approach than the one that I am currently struggling with? Thank you for your patience...
class Program
{
static void Main()
{
Order [] orders = new Order [3];
int tempOrderNumber;
string tempCustomerName;
int tempQtyOrdered;
for (int x = 0; x < orders.Length; ++x) // fill list
{
tempOrderNumber = AskForOrderNumber(orders);
GetData(out tempCustomerName, out tempQtyOrdered);
orders[x] = new Order(tempOrderNumber, tempCustomerName, tempQtyOrdered);
}
Console.ReadLine();
}
private static int AskForOrderNumber(Order [] orders)
{
int tempOrderNumber;
Console.Write("Enter Order Number: ");
int.TryParse(Console.ReadLine(), out tempOrderNumber);
if (orders[0] !=null && IsOrderNumberInUse(tempOrderNumber, orders) == true) //Check for duplicates
{
Console.WriteLine("Duplicate order number");
AskForOrderNumber(orders);
}
return tempOrderNumber;
}
static void GetData(out string tempCustomerName, out int tempQtyOrdered)
{
Console.Write("Enter Customer Name: ");
tempCustomerName = Console.ReadLine();
Console.Write("Enter Quantity Ordered: ");
int.TryParse(Console.ReadLine(), out tempQtyOrdered);
}
private static bool IsOrderNumberInUse(int tempOrderNumber, Order[] orders)
{
foreach (Order order in orders)
{
if (order.OrderNumber == tempOrderNumber)
{
return true;
}
}
return false;
}
class Order
{
private const double PRICE = 19.95;
public int OrderNumber { get; set; }
public string CustomerName { get; set; }
public int QtyOrdered { get; set; }
public double totalPrice
{
get
{
return QtyOrdered * PRICE;
}
}
public override string ToString()
{
return ("\n" + GetType() + "\nCustomer: " + CustomerName + "\nOrder Number: " + OrderNumber +
"\nQuantity: " + QtyOrdered + "\nTotal Order: " + totalPrice.ToString("C2"));
}
public Order(int orderNumber, string customerName, int qtyOrdered)
{
OrderNumber = orderNumber;
CustomerName = customerName;
QtyOrdered = qtyOrdered;
}
public override bool Equals(Object x)
{
bool isEqual;
if(this.GetType() != x.GetType())
isEqual = false;
else
{
Order temp = (Order) x;
if(OrderNumber == temp.OrderNumber)
isEqual = true;
else
isEqual = false;
}
return isEqual;
}
public override int GetHashCode()
{
return OrderNumber;
}
}
}
To fix your problem, I would suggest you use a List<Order>, because lists are resizable I believe they will be a better choice here.
Your current method doesn't work because you don't create order[x] until after you check for it.
Using Lists/Fixed Code
You should instead use the temporary orderNumber, however because the array is empty, you can also get null errors (which can be fixed) when checking for the first time, because of this I would again recommend a List.
List<Order> orders = new List<Order>(); //Orders list
int orderNumber; //Temporary order number
string customerName; //Temporary customer name
int qtyOrdered; //Temporary quantity
for (int x = 0; x < 3; ++x) //Fill List
{
Console.Write("Enter Order Number: ");
int.TryParse(Console.ReadLine(), out orderNumber); //Parse order number
if (IsOrderNumberInUse(orderNumber, orders) == true) //Check for duplicates
{
Console.WriteLine("Duplicate order number");
}
//Get data and add to list
GetData(out customerName, out qtyOrdered);
orders.Add(new Order(orderNumber, customerName, qtyOrdered));
}
Console.ReadLine();
Asking the user again if input is invalid
The example above shows my suggestions to fix your problem and use a List, but if you would like to go further and prompt the user to re-enter the value of it is in use. You can do this by creating a method to ask the user for input, and through recursion, ask them again if in use.
...
for (int x = 0; x < 3; ++x) //Fill List
{
orderNumber = AskForOrderNumber(orders);
//Get data and add to list
GetData(out customerName, out qtyOrdered);
orders.Add(new Order(orderNumber, customerName, qtyOrdered));
}
Console.ReadLine();
}
private static int AskForOrderNumber(List<Order> orders)
{
int orderNumber;
Console.Write("Enter Order Number: ");
int.TryParse(Console.ReadLine(), out orderNumber); //Parse order number
if (IsOrderNumberInUse(orderNumber, orders) == true) //Check for duplicates
{
Console.WriteLine("Duplicate order number");
AskForOrderNumber(orders);
}
return orderNumber;
}
Better method for checking for validation
There is also nothing wrong with your current method for checking for duplicates, but it could be improved with LINQ. (using System.LINQ)
private static bool IsOrderNumberInUse(int orderNumber, List<Order> orders)
{
return orders.Any(o => o.OrderNumber == orderNumber);
}

Error: class does not contain a definition and no extension method

In my code below, it is supposed to do the following tasks:
Prompt the user for values for each Order. Do not allow duplicate order numbers; force the user to reenter the order when a duplicate order number is entered. When five valid orders have been entered, display them all, plus a total of all orders.
The problem is that there are errors in it. I tried to solve the errors by myself but I can't fix it. I've been stuck in these errors for many hours. And another thing, I can't really understand why does it displays that OrderDemo does not contain a definition for Total, OrderNumber, Customer and Quantity. Any help given would be very much appreciated. Thanks!
using System;
class OrderDemo
{
public static void Main()
{
OrderDemo[] order = new OrderDemo[5];
int x, y;
double grandTotal = 0;
bool goodNum;
for (x = 0; x < order.Length; ++x)
{
order[x] = new Order(); //OrderDemo.Order does not contain a constructor that takes 0 arguments
Console.Write("Enter order number");
order[x].OrderNumber = Convert.ToInt32(Console.ReadLine());
goodNum = true;
for (y = 0; y < x; ++y)
{
if (order[x].Equals(order[y]))
goodNum = false;
}
while (!goodNum)
{
Console.Write("sorry, the order number " + order[x].OrderNumber + "is a duplicate. " + "\nPlease reenter: ");
order[x].OrderNumber = Convert.ToInt32(Console.ReadLine());//OrderDemo does not contain a definition for OrderNumber and no extension..
goodNum = true;
for (y = 0; y > x; ++y)
{
if (order[x].Equals(order[y]))
goodNum = false;
}
}
Console.Write("Enter customer name");
order[x].Customer = Console.ReadLine();//OrderDemo does not contain a definition for Customer and no extension..
Console.Write("Enter Quantity");
order[x].Quantity = Convert.ToInt32(Console.ReadLine());//OrderDemo does not contain a definition for Quantity and no extension..
}
Console.WriteLine("\nSummary\n");
for (x = 0; x < order.Length; ++x)
{
Console.WriteLine(order[x].ToString());
grandTotal += order[x].Total; //OrderDemo does not contain a definition for Total and no extension..
}
Console.WriteLine(" Total for all orders is" + grandTotal.ToString("c"));
}
public class Order
{
public int orderNum;
public string cusName;
public int quantity;
public double total;
public const double ItemPrice = 19.95;
public Order(int ordNum, string cusName, int numOrdered)
{
OrderNum = ordNum;
Customer = cusName;
Quantity = numOrdered;
}
public int OrderNum
{
get { return orderNum; }
set { orderNum = value; }
}
public string Customer
{
get { return cusName; }
set { cusName = value; }
}
public int Quantity
{
get
{
return quantity;
}
set
{
quantity = value;
total = quantity * ItemPrice;
}
}
public double Total
{
get
{
return total;
}
}
public override string ToString()
{
return ("Order " + OrderNum + " " + Customer + " " + Quantity +
" #Php" + ItemPrice.ToString("0.00") + " each. " + "The total is Php" + Total.ToString("0.00"));
}
public override bool Equals(Object e)
{
bool equal;
Order temp = (Order)e;
if (OrderNum == temp.OrderNum)
equal = true;
else
equal = false;
return equal;
}
public override int GetHashCode()
{
return OrderNum;
}
}
}
You declared your array as containing OrderDemo objects.
As the error clearly states, OrderDemo doesn't have any properties.
You probably mean Order, which is a different class.
C# provides a default constructor for you, as long as you don't define other constructors which accept parameters. Because you have this:
public Order(int ordNum, string cusName, int numOrdered)
{
OrderNum = ordNum;
Customer = cusName;
Quantity = numOrdered;
}
The default constructor isn't generated. You need to add this:
public Order() { }
...if you want to create objects without passing parameters to it.
Also, as SLaks has pointed out, you have declared your array incorrectly:
OrderDemo[] order = new OrderDemo[5];
Should be this instead:
var order = new Order[5]; // or Order[] order = new Order[5];

C# adding values to an instance after using a constructor

Can I add values to an instance of an object after I have used the constructor?
For instance I have this code. I have to make a list of objects which require a number n, and the time (which are recieved as arguments). The problem is that the time can be anywhere so I can't use it in a constructor.
public List<IAction> Dispatch(string[] arg)
{
int time;
int i = 0;
int j = 0;
List<IAction> t = new List<IAction>(10);
do
{
if (int.Parse(arg[j]) >= 0 && int.Parse(arg[j]) <= 20)
{
t.Add(new ComputeParam(int.Parse(arg[j])));
i++;
j++;
}
else
{
if (arg[i][0] == '/' && arg[i][1] == 't')
{
Options opt = new Options();
j++;
time=opt.Option(arg[i]); //sets the time 0,1000 or 2000
}
}
} while (i != arg.Length);
return t;
}
After finishing making the list can I do something like:
for(int i=0; i<=t.Count; i++)
{
*add time to t[i]*
}
How do I do this?
Thanks in advance!
Edit :
here is the ComputeParam class
public class ComputeParam : IAction
{
int n;
int time;
public ComputeParam()
{
}
public ComputeParam(int n)
{
this.n = n;
}
public void run()
{
Factorial Fact = new Factorial();
Fact.Progression += new Factorial.ProgressEventHandler(Progress);
Console.WriteLine(" ");
Console.Write("\n" + "Partial results : ");
Console.CursorLeft = 35;
Console.Write("Progress : ");
int Result = Fact.CalculateFactorial(n, time);
Console.WriteLine(" ");
Console.WriteLine("The factorial of " + n + " is : " + Result);
Console.WriteLine("Press Enter to continue...");
Console.CursorTop -= 2;
Console.CursorLeft = 0;
Console.ReadLine();
}
public void Progress(ProgressEventArgs e)
{
int result = e.getPartialResult;
int stack_value = e.getValue;
double max = System.Convert.ToDouble(n);
System.Convert.ToDouble(stack_value);
double percent = (stack_value / max) * 100;
Console.CursorLeft = 18;
Console.Write(result + " ");
Console.CursorLeft = 46;
Console.Write(System.Convert.ToInt32(percent) + "% ");
}
}
If the object has a public property, I don't see why not.
Edit: Looks like you need to add a public property to your class. Also note, given that there is a public constructor that takes 0 params, you should also add a property for n.
public class ComputeParam : IAction
{
int _n;
int _time;
public ComputeParam()
{
}
public ComputeParam(int n)
{
this._n = n;
}
public int Time
{
get { return this._time; }
set { this._time = value; }
}
public int N
{
get { return this._n; }
set { this._n = value; }
}
for(int i = 0; i < t.Count; i++)
{
((ComputeParam)t[i]).Time = 6;
}

Categories