2

在我的Class我需要property根据另一个值设置一个值:

public class Quantities
{
    private int _quant;
    public int Quant
    {
        get { return _quant; }
        set
        {
            if (Unit == "K")
            {
                _quant = value / 1000;
            }
            else
            {
                _quant = value;
            }
        }
    }
    public string Unit { get; set; }
}

根据几项测试,我使它工作正常,但我仍然不知道这样做是否安全。
是否有可能在编译器(或JIT)知道它应该分配第一个Quant Property之前评估将?Unit PropertyUnit Property

4

3 回答 3

9

这与编译器或 JIT 无关。您的代码分配值。需要知道分配它们的顺序。

顺便说一句:您的代码表现出时间耦合。最好Unit通过制作属性readonly并提供需要该单元的构造函数来至少使不可更改:

public class Quantities
{
    private readonly string _unit;
    private int _quant;

    public Quantities(string unit)
    {
        if(unit == null) throw new ArgumentNullException("unit");
        _unit = unit;
    }

    public int Quant
    {
        get { return _quant; }
        set
        {
            if (Unit == "K")
            {
                _quant = value / 1000;
            }
            else
            {
                _quant = value;
            }
        }
    }
    public string Unit { get { return _unit; } }
}

此类现在不能以不正确的方式使用。

有关您的课程可以提高的更多点,请参阅Lasse 的回答

于 2013-06-05T09:35:37.250 回答
7

此类外部的代码必须了解这种依赖关系,否则您可能会冒有人在Unit不重新设置的情况下进行更改Quant

var x = new Quantities(); // why no constructor for this?
x.Unit = "K";
x.Quant = 1700;           // why int? this will now be 1, not 1.7
x.Unit = "M";

就个人而言,我会将类设为结构,并使其不可变:

public struct Quantity
{
    private readonly double _Value;
    private readonly string _Unit;

    public Quantity(double value, string unit)
    {
        _Value = value;
        _Unit = unit;
    }

    public double Value
    {
        {
            return _Value;
        }
    }

    public double Unit
    {
        {
            return _Unit;
        }
    }
}

另请注意,我根本没有更改该值,因此:

var x = new Quantity(1700, "K");

表示 1700K,而不是 1.7K。我会避免对数据进行这种“自动”的解释。如果您需要用不同的单位显示值,我会改为构建一个转换系统:

    public Quantity ConvertToUnit(string newUnit)
    {
        var newValue = ... calculate value with new unit
        return new Quantity(newValue, newUnit);
    }
于 2013-06-05T09:39:16.103 回答
2

类不是一个好的设计。不要这样做。

考虑以下代码:

Quantities q1 = new Quantities { Unit = "K", Quant = 1000};
Console.WriteLine(q1.Quant); // Prints 1

// Make a copy of q1

Quantities q2 = new Quantities{ Unit = q1.Unit, Quant = q1.Quant };
Console.WriteLine(q2.Quant); // Prints 0

您会期望通过执行上述基本副本来制作 Quantities 的副本。它并没有告诉你这种设计有多危险。

在上面接受的答案中进行更改后,这仍然是一个问题

如果您使用 Daniel 建议的更改,您仍然会遇到与您的属性 setter 和 getter 不可交换相关的讨厌。当然,您将被迫将单位传递给构造函数,但对象副本仍然无法像用户期望的那样工作:

Quantities q1 = new Quantities("K"){ Quant = 1000};
Console.WriteLine(q1.Quant); // Prints 1

// Make a copy of q1

Quantities q2 = new Quantities(q1.Unit){ Quant = q1.Quant };
Console.WriteLine(q2.Quant); // STILL Prints 0
于 2013-06-05T09:53:37.620 回答