【问题标题】:Using a property to create a total for another property使用一个属性为另一个属性创建总计
【发布时间】:2020-07-19 04:26:41
【问题描述】:

我是 C# 语言的新手,我试图弄清楚如何让我的 Quantity 属性通过将购买的商品数量乘以 12.35 的商品价格来计算最终价格,只要订购的数量是设置。

我在使用Equals() 方法时也遇到了问题。我正在尝试使用 Equals() 方法根据订单号比较 2 个订单,但我在 Visual Studio 中收到警告说 'Order' overrides Object.Equals(object o) but does not override Object.GetHashCode()。我该如何解决这个问题?

这是我的程序:

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);
        }
    }
}

【问题讨论】:

  • “但我在 Visual Studio 中收到警告说” - 请仔细阅读错误消息。它说你已经覆盖了Equals,但没有覆盖GetHashCode。如果你做了它暗示你没有做过的事情,它肯定会消失,对吧?
  • 我通过检查您的个人资料并查看您的描述来解决这个问题......但我的主要问题是我的最终输出总是告诉我我的 Total 是 0,我试图弄清楚如何为了解决这个问题,我已经尝试多次查找这个问题并搜索了论坛,但我没有找到直接的答案。
  • 请针对每个帖子提出 一个 问题。确保显示与该单个问题相关的just 代码(查看minimal reproducible example 以获取提示)。 Edit 问题,以避免它被关闭为过于宽泛或重复“如何实现 equals”(因为它更容易找到)。
  • 那这不是你的previous question 的复制品吗?同样,GetTotal() 中的变量 double Total 和您的字段 private readonly double Total 彼此没有关系。
  • 有点像,但我发布了这个问题而不是紧急情况,所以当我回来时,我觉得我没有得到任何明确的答案或帮助,所以我觉得我应该重新发布问题@John

标签: c# methods properties


【解决方案1】:

该属性就像一个函数一样工作。您可以将Total 声明为只读属性,并声明一个执行乘法运算的getter。

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

重写 Object.GetHashCode() 很容易。如果两个项目相同,您应该创建一个返回相同值的函数。 因为您使用 OrderNum 作为识别订单的唯一方法。只需返回它即可完成工作。

public override int GetHashCode() {
    return this.OrderNum;
}

【讨论】:

    【解决方案2】:

    我想这就是你要找的东西:

    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,
            });
        }
    }
    

    按如下方式使用:

    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);
            }
        }
    }
    

    有输出

    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
    

    【讨论】:

      猜你喜欢
      • 2018-07-14
      • 1970-01-01
      • 2017-08-28
      • 2017-06-07
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 2017-01-29
      • 2020-05-17
      相关资源
      最近更新 更多