在我的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; }
}
根据几项测试,我认为它工作正常,但我仍然不知道这样做是否安全
是Quant Property
是否有可能在Unit Property
之前进行评估,或者编译器(或JIT)是否知道它应该首先分配Unit Property
?
答案 0 :(得分:8)
这与编译器或JIT无关。 您的代码会分配值。 您需要知道应该分配的顺序。
顺便说一句:您的代码展示了temporal coupling。最好通过创建属性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's answer。
答案 1 :(得分:6)
此课程外部的代码必须知道此依赖关系,否则您可能会有人更改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);
}
答案 2 :(得分: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
您可以通过执行如上所述的基本复制来制作数量副本。它没有告诉你这种设计有多危险。
在上面接受的答案中进行更改后仍然存在问题
如果您使用Daniel建议的更改,您仍然会遇到与您的属性设置器相关的讨厌,并且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