0

I am new to the language C# and I am trying to figure out how I can get my Quantity property to calculate the final price by multiplying the quantity of items bought and then the item price of 12.35 anytime the quantity ordered is set.

I am also having a problem with using the Equals() method. I am trying to use the Equals() method to compare 2 orders based on their order number but I am receiving a warning in my Visual Studio saying that 'Order' overrides Object.Equals(object o) but does not override Object.GetHashCode(). How do I fix this?

Here is my program:

using System;

namespace Order 
{
    class Program
    {
        static void Main(string[] args)
        {
            // creating the orders
            Order order1 = new Order(1, "Joe Bob", 2);
            Order order2 = new Order(3, "Sally Bob", 4);
            Order order3 = new Order(1, "Jimmy Bob", 5);
            Console.WriteLine(order1.ToString() + "\n");
            Console.WriteLine(order2.ToString() + "\n");
            Console.WriteLine(order3.ToString() + "\n");

            //checks for duplicates
            CheckDuplicate(order1, order2);
            CheckDuplicate(order2, order3);
            CheckDuplicate(order1, order3);
        }
        // output for duplicates
        public static void CheckDuplicate(Order firstOrder, Order secondOrder)
        {
            if (firstOrder.Equals(secondOrder))
            {
                Console.WriteLine("The two orders are the same!");
            }
            else
            {
                Console.WriteLine("The two orders are not the same!");
            }
        }
    }

    class Order
    {
        // setting properties
        public int OrderNum { get; set; }
        public string CustomerName { get; set; }
        public double Quantity;
        private readonly double Total;
        // total price
        public double GetTotal()
        {
            double itemPrice = 12.35;
            double Total = Quantity * itemPrice;
            return Total;
        }
        // equals to method
        public override bool Equals(Object o)
        {
            bool isEqual = true;
            if (this.GetType() != o.GetType())
                isEqual = false;
            else
            {
                Order temp = (Order)o;
                if (OrderNum == temp.OrderNum)
                    isEqual = true;
                else
                    isEqual = false;
            }
            return isEqual;
        }
        // default constructor
        public Order(int OrderNum, string CustomerName, double Quantity)
        {
            this.OrderNum = OrderNum;
            this.CustomerName = CustomerName;
            this.Quantity = Quantity;
        }
        // returns final output
        public override string ToString()
        {
            return ("Order Number       : " + OrderNum) + "\n" + ("Customer name      : " + CustomerName) + "\n" + ("Quantity Ordered   : " + Quantity) + "\n" + ("Totatl Price       : " + Total);
        }
    }
}
dorlox
  • 75
  • 1
  • 7
  • 1
    _"but I am receiving a warning in my Visual Studio saying that"_ - Read the error message very carefully. It says that you have overriden `Equals` but not `GetHashCode`. If you did what it implies you haven't done, it would surely go away, right? – ProgrammingLlama Apr 07 '20 at 03:16
  • I fixed that by checking your profile and seeing your description...but my main problem is that my final output is always telling me my `Total` is 0 and I'm trying to figure out how to fix this and I've tried looking this up multiple time and scoured the forums and I don't find a direct answer. – dorlox Apr 07 '20 at 03:27
  • Please ask *one* question per post. Make sure to show *just* code relevant to that single question (review [MCVE] for hints). [Edit] question to avoid it being closed as too broad or duplicate of "how to implement equals" (as it is easier to find). – Alexei Levenkov Apr 07 '20 at 03:28
  • Isn't this a duplicate of your [previous question](https://stackoverflow.com/questions/61070842/my-order-total-is-never-assigned-to-and-will-always-have-its-value-set-to-0) then? Again the variable `double Total` in `GetTotal()` and your field `private readonly double Total` have no relationship to each other. – ProgrammingLlama Apr 07 '20 at 03:31
  • It kind of is but I posted that question than I had an emergency so when I got back I feel like I didn't get any clear answer or help so I felt like I should re-post the question @John – dorlox Apr 07 '20 at 03:36
  • Avoid having the same name for the namespace as a class. In fact, VS will error on that one. – John Alexiou Apr 08 '20 at 00:23

2 Answers2

1

The property works just like a function. You can declare Total as a readonly property, and declare a getter in which it does the multiply math.

public double Quantity;
public double Total {
    get {
        const double itemPrice = 12.35;
        return Quantity * itemPrice;
    }
}

Overriding the Object.GetHashCode() is easy. You should create a function which returns a same value if two items are identical. As you are using the OrderNum as the only way to identify orders. Simply returning this will do the job.

public override int GetHashCode() {
    return this.OrderNum;
}
Nemo Zhang
  • 146
  • 7
0

I think this is what you are looking for:

public sealed class Order : IEquatable<Order>
{
    // Properties & Fields
    public int OrderNum { get; set; }
    public string CustomerName { get; set; }
    public double Quantity { get; set; }
    public double ItemPrice { get; set; } 
    public double TotalPrice => Quantity*ItemPrice;

    // Constructor
    public Order(int orderNum, string customerName, double quantity, double itemPrice = 12.35)
    {
        this.OrderNum = orderNum;
        this.CustomerName = customerName;
        this.Quantity = quantity;
        this.ItemPrice = itemPrice;
    }

    // Equality

    /// <summary>
    /// Equality overrides from <see cref="System.Object"/>
    /// </summary>
    /// <param name="obj">The object to compare this with</param>
    /// <returns>False if object is a different type, otherwise it calls <code>Equals(Order)</code></returns>
    public override bool Equals(object obj)
    {
        if (obj is Order order)
        {
            // Uses pattern matching when `obj` is of type `Order`
            return Equals(order);
        }
        return false;
    }

    /// <summary>
    /// Checks for equality among <see cref="Order"/> classes
    /// </summary>
    /// <param name="other">The other <see cref="Order"/> to compare it to</param>
    /// <returns>True if equal</returns>
    public bool Equals(Order other)
    {
        return OrderNum.Equals(other?.OrderNum);
    }

    /// <summary>
    /// Calculates the hash code for the <see cref="Order"/>
    /// </summary>
    /// <returns>The int hash value</returns>
    public override int GetHashCode()
    {
        return (17+23*OrderNum.GetHashCode());
    }

    // Display
    public override string ToString()
    {
        return string.Join(Environment.NewLine, new string[] {
            $"Order Number       : {OrderNum}",
            $"Customer name      : {CustomerName}",
            $"Item Price         : {ItemPrice:F2}",
            $"Quantity Ordered   : {Quantity:F3}",
            $"Total Price        : {TotalPrice:F2}",
            Environment.NewLine,
        });
    }
}

to be used as follows:

class Program
{
    static void Main(string[] args)
    {
        // creating the orders
        List<Order> orders = new List<Order>();
        orders.Add(new Order(1, "Joe Bob", 2));
        orders.Add(new Order(3, "Sally Bob", 4));
        orders.Add(new Order(1, "Jimmy Bob", 5));

        Console.WriteLine("List of all orders.");
        foreach (var order in orders)
        {
            Console.WriteLine(order);
        }

        Console.WriteLine("Found the following duplicates.");
        // Code taken from: https://stackoverflow.com/a/18547390/380384
        // It uses the `IEquatable<>` interface to check for duplicates.
        foreach (var item in orders.GroupBy((order) => order).Where(grp => grp.Count()>1))
        {
            Console.WriteLine(item.Key);
        }
    }
}

with output

List of all orders.
Order Number       : 1
Customer name      : Joe Bob
Item Price         : 12.35
Quantity Ordered   : 2.000
Total Price        : 24.70


Order Number       : 3
Customer name      : Sally Bob
Item Price         : 12.35
Quantity Ordered   : 4.000
Total Price        : 49.40


Order Number       : 1
Customer name      : Jimmy Bob
Item Price         : 12.35
Quantity Ordered   : 5.000
Total Price        : 61.75


Found the following duplicates.
Order Number       : 1
Customer name      : Joe Bob
Item Price         : 12.35
Quantity Ordered   : 2.000
Total Price        : 24.70
John Alexiou
  • 28,472
  • 11
  • 77
  • 133