我的作业有问题。我有一个实例变量price,应该具有get方法而没有set方法。我已经通过构造函数计算并分配了这个价格变量。我注意到,如果您将宽度或高度值更改为Main
中的另一个数字,则价格变量不会改变。我添加了一个updatePrice()
方法,该方法在Main
中显式调用时可以使用,但希望通过height / width set方法自动实现。我现在无法使其正常工作。
更改有效的宽度变量后,显式调用updatePrice()
。
using System;
using static System.Console;
class Photo
{
private int width { get; set; }
private int height { get; set; }
protected double price;
public int Width {
get
{
return width;
}
set
{
updatePrice(value, height);
width = value;
}
}
public int Height {
get
{
return height;
}
set
{
updatePrice(width, value);
height = value;
}
}
public Photo(int width, int height)
{
this.width = width;
this.height = height;
if (width == 8 && height == 10)
price = 3.99;
else if (width == 10 && height == 12)
price = 5.99;
else
price = 9.99;
}
public virtual double Price
{
get
{
return price;
}
}
public String ToString()
{
return GetType() + " with a width of " + width + " and a height of " + height +
" with a base price of " + Price.ToString("C2");
}
// used to be updatePrice() w/ no parameters
public void updatePrice(int width, int height)
{
if (width == 8 && height == 10)
price = 3.99;
else if (width == 10 && height == 12)
price = 5.99;
else
price = 9.99;
}
static void Main()
{
Photo photo = new Photo(10, 12);
WriteLine(photo.ToString());
photo.height = 4;
// updatePrice();
WriteLine(photo.ToString());
}
}
宽度为10高度为12的照片,底价为5.99美元 //将高度更改为4 宽度为10且高度为4的照片,底价为5.99美元 //价格应为9.99美元
答案 0 :(得分:1)
不是更新价格,而是在Price
属性中动态计算价格。像这样,您可以确保它始终反映当前状态。
public virtual double Price
{
get
{
if (width == 8 && height == 10) return 3.99;
if (width == 10 && height == 12) return 5.99;
return 9.99;
}
}
我刚刚使用上面的属性进行了此速度测试:
var stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1_000_000; i++) {
photo.Height = 4;
double price = photo.Price;
photo.Height = 10;
price = photo.Price;
}
stopWatch.Stop();
Console.WriteLine("Elapsed ms: " + stopWatch.ElapsedMilliseconds);
请注意,它计算价格为200万次。执行需要67毫秒!因此,尝试优化此计算是不值得的。您只节省了几纳秒。但是将计算结果放入属性中可以简化代码并使其更可靠。
还请注意,您必须覆盖从ToString
继承的现有object
方法。
public override string ToString()
{
return $"{GetType()}: width = {width}, height = {height}, base price = {Price:C2}";
}
然后您可以使用
打印照片WriteLine(photo);
as WriteLine
现在自动使用此方法。我还使用了字符串插值。这比字符串连接更具可读性。
答案 1 :(得分:1)
这里是按照我对问题的评论所建议的那样重构了您的代码,其中updatePrice
标记为保护虚拟以允许多态,在.Name
中添加了ToString
,并且我删除了私有的无用访问器字段:
class Photo
{
private int width;
private int height;
protected double price;
public int Width {
get
{
return width;
}
set
{
width = value;
updatePrice();
}
}
public int Height {
get
{
return height;
}
set
{
height = value;
updatePrice();
}
}
public Photo(int width, int height)
{
this.width = width;
this.height = height;
updatePrice();
}
public virtual double Price
{
get
{
return price;
}
}
public override string ToString()
{
return GetType().Name +
" with a width of " + width +
" and a height of " + height +
" with a base price of " + Price.ToString("C2");
}
protected virtual void updatePrice()
{
if (width == 8 && height == 10)
price = 3.99;
else if (width == 10 && height == 12)
price = 5.99;
else
price = 9.99;
}
}
因此您无需从外部调用updatePrice:
static void Main()
{
Photo photo = new Photo(10, 12);
WriteLine(photo.ToString());
photo.height = 4;
WriteLine(photo.ToString());
}