C# 在另一个属性设置器中使用属性值

C# 在另一个属性设置器中使用属性值,c#,properties,.net-3.5,C#,Properties,.net 3.5,在我的类中我需要根据另一个设置一个属性值: public class Quantities { private int _quant; public int Quant { get { return _quant; } set { if (Unit == "K") { _quant = value / 1000; }

在我的
类中
我需要根据另一个设置一个
属性
值:

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)是否知道应该首先分配
单元属性

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

顺便说一句:你的代码展示。最好至少使
单元
不可更改,方法是使属性为只读,并提供需要该单元的构造函数:

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; } }
}
该类现在不能以错误的方式使用


有关您的课程可以改进的更多点,请参阅。

此课程外部的代码必须了解此依赖关系,否则您可能会有人在不重新设置数量的情况下更改单元

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

这门课设计得不好。不要这样做

考虑以下代码:

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建议的更改,那么仍然存在与属性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

我将定义一个方法来返回值。或者在设置
Quant
之前一定要记住设置
Unit
。我真的不会走这条路。有一个一致的单位(不可设置)和两种不同的方法来设置值。否则,如果设置
Quant
,然后更改
Unit
,这意味着什么?如果将属性设置为X后,它不等于X,那么也会非常混乱。请使用正确命名的方法来执行此类操作。