Checking if a list of objects contains a property - c#

Hi i have a list of objects and i need to find out if the id i have is already in the list. In the object class i have set the id and i just want to find out if the one that is entered in the Ui is already in use.
The Class
class Product
{
private string name = "";
private int id = 0;
private decimal Pvalue = 0.00m;
private static int lastId = 1;
public Product(string namep, decimal valuep)
{
this.name = namep;
this.id = lastId++;
this.Pvalue = valuep;
}
public override string ToString()
{
return name + " " + id + " "+ Pvalue;
}
public bool Equals(Product p)
{
return (p.id == this.id);
}
}
Me trying to work it out:
int id;
bool test = int.TryParse(textBoxId.Text, out id);
if(test)
{
if(Inv.Contains(id))
{
label2.Text = "you already have this id";
}else
{
label2.Text = "you can use this id";
}
}
If any one has a idea on why this is not working or a better way it would save my back side thank you.

Change private int id = 0; to public int Id { get; set; }. Also, change all the references from id to Id.
Add a using System.Linq to your business logic file.
Change if (Inv.Contains(id)) to if (Inv.Any(x => x.Id == id))

Related

Why isn't my property doing the check?

My constructor get info from the form. The 'name' is addressed with 'aName' (from the constructor), then there has to be a check done with prop 'NameCheck'. but if I compile it, it return an empty string. Any ideas?
Code:
---- Class ----
//Fields
private List<Create> Characters;
private string name;
private int health;
private int mSpeed;
private Role role;
private Speciality speciality;
//Properties
public string NameCheck
{
get {
return name;
}
set
{
if (string.IsNullOrEmpty(name))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}
//Constructor
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.name = aName;
this.health = aHealth;
this.mSpeed = aMSpeed;
this.role = aRole;
this.speciality = aSpeciality;
Characters = new List<Create>();
}
---- Form ----
Create character = new Create(tbName.Text, health, mspeed, aLane, aSpecial);
Characters.Add(character);
cbSummary.Items.Add(character.ToString());
PS: cbSummary is a combobox.
EDIT:
public override string ToString()
{
return "Name: " + NameCheck + " - Health: " + health + " - MovementSpeed: " + mSpeed + " - Role: " + role + " - Speciality: " + speciality;
}
You should set this.NameCheck instead of this.name in your constructor
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.NameCheck = aName;
also you should check value for emptiness or being null instead of name in your property setter
set
{
if (string.IsNullOrEmpty(value))
{
You have a small typo in your property:
public string NameCheck
{
get {
return name;
}
set
{
// You need to check value, not name.
if (string.IsNullOrEmpty(value))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}
In your constructor you should use your NameCheck property rather than the name field:
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.NameCheck = aName;
this.health = aHealth;
this.mSpeed = aMSpeed;
this.role = aRole;
this.speciality = aSpeciality;
Characters = new List<Create>();
}
Also as Paddy said you are doing an incorrect check in the set body of NameCheck:
public string NameCheck
{
get
{
return name;
}
set
{
if (string.IsNullOrEmpty(value))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}

containing type does not implement interface 'System.IComparable' error

namespace Theprogram.cs
{
class Program
{
static void Main(string[] args)
{
CreditCustomer[] creditCustomer = new CreditCustomer[5];
int x, y;
bool goodNum;
for (x = 0; x < creditCustomer.Length; ++x)
{
creditCustomer[x] = new CreditCustomer();
Console.Write("Enter customer number ");
creditCustomer[x].CustomerNumber = Convert.ToInt32(Console.ReadLine());
goodNum = true;
for (y = 0; y < x; ++y)
{
if (creditCustomer[x].Equals(creditCustomer[y]))
goodNum = false;
}
while (!goodNum)
{
Console.Write("Sorry, the customer number " +
creditCustomer[x].CustomerNumber + " is a duplicate. " +
"\nPlease reenter ");
creditCustomer[x].CustomerNumber = Convert.ToInt32(Console.ReadLine());
goodNum = true;
for (y = 0; y < x; ++y)
{
if (creditCustomer[x].Equals(creditCustomer[y]))
goodNum = false;
}
}
Console.Write("Enter name ");
creditCustomer[x].CustomerName = Console.ReadLine();
Console.Write("Enter age ");
creditCustomer[x].Rate = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter amount due ");
creditCustomer[x].AmountDue = Convert.ToDouble(Console.ReadLine());
}
Array.Sort(creditCustomer);
Array.Sort(customer);
}
}
class Customer : IComparable<Customer>
{
private int customerNumber;
public int CustomerNumber
{
get
{
return customerNumber;
}
set
{
customerNumber = value;
}
}
private string customerName;
public string CustomerName
{
get
{
return customerName;
}
set
{
customerName = value;
}
}
private double amountDue;
public double AmountDue
{
get
{
return amountDue;
}
set
{
amountDue = value;
}
}
public Customer(int num, string name, int amt)
{
CustomerNumber = num;
CustomerName = name;
AmountDue = amt;
}
public Customer(): this(9, "ZZZ", 0)
{
}
public override bool Equals(Object e)
{
bool equal;
Customer temp = (Customer)e;
if (this.CustomerNumber == temp.CustomerNumber)
equal = true;
else
equal = false;
return equal;
}
public override int GetHashCode()
{
return CustomerNumber;
}
public override string ToString()
{
return (GetType() + " Credit Customer " + CustomerNumber + " " + CustomerName +
" Amount Due is " + AmountDue.ToString("C") + " Interest rate is ");
}
protected virtual int IComparable.CompareTo(Object o)
{
int returnVal;
Customer temp = (Customer)o;
if (this.CustomerNumber >
temp.CustomerNumber)
returnVal = 1;
else
if (this.CustomerNumber < temp.CustomerNumber)
returnVal = -1;
else
returnVal = 0;
return returnVal;
}
}
class CreditCustomer : Customer, IComparable<CreditCustomer>
{
public int Rate {get; set;}
int MonthlyPayment { get; set; }
public CreditCustomer(int customerNumber, string customerName, int amountDue, int Rate) : base(customerNumber, customerName, amountDue)
{ }
public CreditCustomer(): this(0, "", 0, 0)
{ }
public override string ToString()
{
return (GetType() + " Credit Customer " + CustomerNumber + " " + CustomerName +
" Amount Due is " + AmountDue.ToString("C") + " Interest rate is " + Rate + " Monthly Payment is " + MonthlyPayment);
}
int IComparable.CompareTo(object o)
{
int returnVal;
CreditCustomer temp = (CreditCustomer)o;
if (this.CustomerNumber > temp.CustomerNumber)
returnVal = 1;
else
if (this.CustomerNumber < temp.CustomerNumber)
returnVal = -1;
else
returnVal = 0;
return returnVal;
}
}
}
I am having trouble implementing Icomparable in C# for my parent and child classes as I get the error:
does not implement interface member'System.IComparable.CompareTo
I really need help on how to implement the Icomparable interface so that I can use the compareTo method on my array of object. Any help would be greatly appreciated.
If you're using Visual Studio and are not sure how to implement an interface, just right click IComparable in the class declaration
class CreditCustomer : Customer, IComparable<CreditCustomer>
and select Implement Interface and any of the two options.
The correct signature for the implementation in CreditCustomer would be either:
public int CompareTo(CreditCustomer other)
{
}
or
int IComparable<CreditCustomer>.CompareTo(CreditCustomer other)
{
}
Note that the second signature would hide the method unless you cast the object to IComparable<CreditCustomer>.
As SLaks mentioned in his comment, there are, in fact, two different interfaces that are named IComparable which can be easily confused:
IComparable is an older, non-generic interface which allows comparison between an object and any other object. There's no type checking - your CreditCustomer can be compared to an int or a List<string> or anything. This interface defines a single method, CompareTo(object obj). This is the method you have in your class.
IComparable<T> is a newer, generic interface. It's very similar to IComparable, but enforces type checking - it only compares T to T, so you don't have to write a lot of boilerplate code making sure that someone didn't try to compare your CreditCustomer to a Dog or something. It also defines a single method - CompareTo(T obj). This is the interface that you marked your class as implementing.
Despite being similarly named, these two are, as far as the compiler is concerned, two different interfaces. If you don't have a CompareTo method that accepts a CreditCustomer argument, you're not implementing IComparable<CreditCustomer>, and that's why it's giving you an error. Either change your method signature to match the interface, or change the interface you're using to one that matches the method signature. Probably the former.

C# array to save data

I am new with C# and i have a problem. Actually it's my first year in college and in programming and i have a problem with arrays. I've made a class with 3 constructors and 1 method in Windows Form Application. The problem is that i want to store data from three textBoxes - that the user is typing- into an array of 10 using a button. and i don't know how to do it.
public class Employee
{
private int idnum;
private string flname;
private double annual;
public Employee()
{
idnum = 0;
flname = "";
annual = 0.0;
}
public Employee(int id, string fname)
{
idnum = id;
flname = fname;
annual = 0.0;
}
public Employee(int id, string fname, double ann)
{
idnum = id;
flname = fname;
annual = ann;
}
public int idNumber
{
get { return idnum; }
set { idnum = value; }
}
public string FLName
{
get { return flname; }
set { flname = value; }
}
public double Annual
{
get { return annual; }
set { annual = value; }
}
public string Message()
{
return (Convert.ToString(idnum) + " " + flname + " " + Convert.ToString(annual));
}
}
First of all you should add on this form 3 textboxe elements and name it in a next manner textBoxId, textBoxFLName, textBoxAnnual
Also you have to add a button. Let's call it btnSave
Write an event OnClick for this button. In this method we must read all data which user fill in on the form.
List<Employee> allEmployees = new List<Employee>();
private void buttonSave_Click(object sender, EventArgs e)
{
//read user input
int empId = Int32.Parse(textBoxId.Text);
string empFlName = textBoxFLName.Text;
double empAnnual = double.Parse(textBoxAnnual.Text);
// create new Employee object
Employee emp = new Employee(empId, empFlName, empAnnual);
// add new employee to container (for example array, list, etc).
// In this case I will prefer to use list, becouse it can grow dynamically
allEmployees.Add(emp);
}
And you can also rewrite your code in a little bit shortest manner:
public class Employee
{
public int IdNum { get; set; }
public string FlName { get; set; }
public double Annual { get; set; }
public Employee(int id, string flname, double annual = 0.0)
{
IdNum = id;
FlName = flname;
Annual = annual;
}
public override string ToString()
{
return (Convert.ToString(IdNum) + " " + FlName + " " + Convert.ToString(Annual));
}
}

Comparing user input to previously entered values

I am having a problem getting my program to check the input previous and compare it so the user cannot duplicate an order number. Right now the program will run all the way through and look the way I want, but it accepts duplicate order numbers while I would like it to inform the user and ask them to reenter. The problem seems to be that my check[y] array does not contain any value when I compare it. How do I get this array to contain the previously entered order numbers so it will display the error message. I am just going to post the entire code so you can see what I have done so far. Others have suggested the List type, but I am a student and have not learned this yet. I believe I am supposed to use the Equals method. Any help would be appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Assignment6_Hergott
{
class Order : IComparable <Order>
{
public int orderNumber { get; set; }
public string customerName { get; set; }
public int quanityOrdered { get; set; }
public double total;
public const double priceEach = 19.95;
public Order()
{
}
public Order(int number, string name, int quanity)
{
number = orderNumber;
name = customerName;
quanity = quanityOrdered;
}
public double totalPrice
{
get
{
return total;
}
}
public int CompareTo(Order o)
{
return this.orderNumber.CompareTo(o.orderNumber);
}
public override bool Equals(Object e)
{
bool equal;
Order temp = (Order)e;
if (orderNumber == temp.orderNumber)
equal = true;
else
equal = false;
return equal;
}
public override int GetHashCode()
{
return Convert.ToInt32(orderNumber);
}
public override string ToString()
{
return "ShippedOrder " + orderNumber + " " + customerName + " " + quanityOrdered +
" # " + priceEach + " each.";
}
}
class ShippedOrder : Order
{
public const int shippingFee = 4;
public override string ToString()
{
return base.ToString() + " Shipping is " + shippingFee + " Total is " + totalPrice;
}
}
class Program
{
static void Main(string[] args)
{
double sum = 0;
ShippedOrder[] orderArray = new ShippedOrder[5];
ShippedOrder[] check = new ShippedOrder[5];
bool wrong = true;
for (int x = 0; x < orderArray.Length; ++x)
{
orderArray[x] = new ShippedOrder();
Console.Write("Enter order number: ");
orderArray[x].orderNumber = Convert.ToInt32(Console.ReadLine());
for (int y = 0; y < x; y++)
{
check[y] = new ShippedOrder();
if (orderArray[x].Equals(check[y]))
wrong = false;
while (!wrong)
{
Console.WriteLine("Sorry, the order number {0} is a duplicate.
\nPlease reenter: ", orderArray[x].orderNumber);
for (y = 0; y < x; y++)
{
if (orderArray[x].Equals(check[y]))
wrong = false;
}
check[y] = orderArray[x];
}
}
Console.Write("Enter cusomer name: ");
orderArray[x].customerName = Console.ReadLine();
Console.Write("Enter quanity: ");
orderArray[x].quanityOrdered = Convert.ToInt32(Console.ReadLine());
orderArray[x].total = orderArray[x].quanityOrdered * Order.priceEach +
ShippedOrder.shippingFee;
sum += orderArray[x].total;
}
Array.Sort(orderArray);
for (int x = 0; x < orderArray.Length; x++)
{
Console.WriteLine(orderArray[x].ToString());
}
Console.WriteLine();
Console.WriteLine("Total for all orders is {0:c} ", sum);
}
}
}
I had a few minutes so I changed my answer to show you one way it could be done. If you just copy/paste this you'll be doing yourself a disservice, though (and your instructor will probably be able to tell). Take a look at the solution and see how it differs from yours. I hesitated to post a full solution but I thought this might be an okay way for you to figure out what you'd done wrong.
namespace ConsoleApplication2
{
using System;
using System.Linq;
public class Order : IComparable<Order>
{
public const double PriceEach = 19.95;
public Order()
{
}
public Order(int number, string name, int quanity)
{
this.OrderNumber = number;
this.CustomerName = name;
this.QuanityOrdered = quanity;
}
public int OrderNumber { get; set; }
public string CustomerName { get; set; }
public int QuanityOrdered { get; set; }
public int CompareTo(Order o)
{
return this.OrderNumber.CompareTo(o.OrderNumber);
}
public override bool Equals(object e)
{
int compareTo;
int.TryParse(e.ToString(), out compareTo);
return this.OrderNumber == compareTo;
}
public override int GetHashCode()
{
return Convert.ToInt32(this.OrderNumber);
}
public override string ToString()
{
return "Shipped order number " + this.OrderNumber + " for customer " + this.CustomerName + " " + this.QuanityOrdered +
" # $" + PriceEach + " each.";
}
}
public class ShippedOrder : Order
{
public const int ShippingFee = 4;
public double TotalPrice
{
get
{
return (this.QuanityOrdered * PriceEach) + ShippingFee;
}
}
public override string ToString()
{
return base.ToString() + " Shipping is $" + ShippingFee + ". Total is $" + this.TotalPrice;
}
}
public class Program
{
private static readonly int[] OrderNumbers = new int[5];
private static readonly ShippedOrder[] ShippedOrders = new ShippedOrder[5];
public static void Main(string[] args)
{
double sum = 0;
for (var i = 0; i < OrderNumbers.Length; i++)
{
OrderNumbers[i] = InputOrderNumber();
var name = InputCustomerName();
var quantity = InputQuantity();
ShippedOrders[i] = new ShippedOrder { CustomerName = name, QuanityOrdered = quantity, OrderNumber = OrderNumbers[i] };
sum += ShippedOrders[i].TotalPrice;
}
Array.Sort(ShippedOrders);
foreach (var t in ShippedOrders)
{
Console.WriteLine(t.ToString());
}
Console.WriteLine();
Console.WriteLine("Total for all orders is {0:c} ", sum);
Console.WriteLine();
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
private static int InputOrderNumber()
{
Console.Write("Enter order number: ");
var parsedOrderNumber = InputNumber();
if (ShippedOrders.Any(shippedOrder => shippedOrder != null && shippedOrder.OrderNumber.Equals(parsedOrderNumber)))
{
Console.WriteLine("Order number {0} is a duplicate.", parsedOrderNumber);
return InputOrderNumber();
}
return parsedOrderNumber;
}
private static string InputCustomerName()
{
Console.Write("Enter customer name: ");
var customerName = Console.ReadLine();
if (customerName == null || string.IsNullOrEmpty(customerName.Trim()))
{
Console.WriteLine("Customer name may not be blank.");
return InputCustomerName();
}
return customerName;
}
private static int InputQuantity()
{
Console.Write("Enter quantity: ");
return InputNumber();
}
private static int InputNumber()
{
int parsedInput;
var input = Console.ReadLine();
if (!int.TryParse(input, out parsedInput))
{
Console.WriteLine("Enter a valid number.");
return InputNumber();
}
return parsedInput;
}
}
}
my check[y] array does not contain any value when I compare it. How do
I get this array to contain the previously entered order numbers
If you want check[] to contain order numbers, it needs to be of the type of order number (an int, in this case). So whenever you add a new order to the orderArray, also add its number to the check array. Then you can test against earlier numbers.
If this doesn't solve your problem, add a follow-up question as a comment telling us what you tried and we can go from there.

Get the properties of objects in array

I have a small problem here.
I have an array which holds some objects (which have properties, duh)
Now I want to sort them by an int property that they have. My qustion is not how to sort them, but how do I read the value of the property of the objects in the array?
private void WriteHighscoreToFile(int groesse, int minenAnzahl, int zeit, string name)
{
using (StreamWriter sw = new StreamWriter(#"C:\Users\tstadler\Desktop\Highscore.txt", true))
{
sw.WriteLine("Spieler: " + name + " Punkte: " + (groesse * minenAnzahl - zeit * 2) + " Groesse: " + groesse + " Minenanzahl " + minenAnzahl + " Zeit: " + zeit);
}
using (StreamReader sr = new StreamReader(#"C:\Users\tstadler\Desktop\Highscore.txt", true))
{
List<CreateNewHighscore> highScores = new List<CreateNewHighscore>();
while (sr.ReadLine() != null)
{
_objectProperties = sr.ReadLine().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
highScores.Add(new CreateNewHighscore(_objectProperties));
highscoreCount++;
}
_highscoresArray = highScores.ToArray();
vergleicheArray(_highscoresArray);
}
}
The Class:
public class CreateNewHighscore
{
public string _name;
public int _punkte;
public int _groesse;
public int _minenAnzahl;
public int _zeit;
public CreateNewHighscore(string[] infos)
{
_name = infos[1];
_punkte = int.Parse(infos[5]) * int.Parse(infos[7]) - 2 * int.Parse(infos[9]);
_groesse = int.Parse(infos[5]);
_minenAnzahl = int.Parse(infos[7]);
_zeit = int.Parse(infos[9]);
} }
My qustion is not how to sort them, but how do I read the value of the property of the objects in the array?
You expose it as a property; for example:
class CreateNewHighscore
{
string _name;
int _punkte, _groesse, _minenAnzahl, _zeit;
public string Name { get { return _name; } }
public int Punkte { get { return _punkte; } }
public int Groesse { get { return _groesse; } }
public int Zeit { get { return _zeit; } }
public int MinenAnzahl { get { return _minenAnzahl; } }
// constructor not shown
}
Then you can access that member from any array / list; for example:
highScores.Sort((x,y) => x.Punkte.CompareTo(y.Punkte));
or:
int firstPunkte = _highscoresArray[0].Punkte;
Your array is of type CreateNewHighscore[] so if you want to access property in classic way just use following line.
_highscoresArray[i].YourIntProperty
where "YourIntProperty" is desired int property.
Use LINQ OrderBy method:
_highscoresArray = highScores.OrderBy(h => h.Punkte).ToArray();
Where Punkte is a property of your CreateNewHighscore class:
public int _punkte; // public field
public Punkte // public property
{
get { return _punkte; }
set { _punkte = value; } // you may not need setter
}
BTW currently your class DO NOT have any properties. There are only public (after your last edit) fields. If you want to sort by field value then:
_highscoresArray = highScores.OrderBy(h => h._punkte).ToArray();
But I advice you to make fields private, or use auto implemented properties instead. And rename your class. Name is really awful and sounds like method name.
public class CreateNewHighscore
{
public string Name { get; private set; }
public int Punkte { get; private set; }
public int Groesse { get; private set; }
public int MinenAnzahl { get; private set; }
public int Zeit { get; private set; }
public CreateNewHighscore(string[] infos)
{
// check infos count
Name = infos[1];
Punkte = int.Parse(infos[5]) * int.Parse(infos[7]) -
2 * int.Parse(infos[9]);
Groesse = int.Parse(infos[5]);
MinenAnzahl = int.Parse(infos[7]);
Zeit = int.Parse(infos[9]);
}
}

Categories

Resources