通过其他实例变量设置方法更新实例变量

时间:2019-11-03 15:40:05

标签: c# oop instance-variables

我的作业有问题。我有一个实例变量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美元

2 个答案:

答案 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());
}