简体   繁体   English

getter / setter中的属性名称

[英]Property name in getter/setter

I am creating some properties and came across a scenario I haven't seen before. 我正在创建一些属性,并遇到了一个我之前从未见过的场景。

Consider 考虑

private double _temperature;
private double _maxTemp;

public double Temperature
{
    get { return _temperature; }
    set { _temperature = value; }
}
public double MaxTemp
{
    get { return _maxTemp; }
    set { _maxTemp = value; }
}
public bool IsTempToHigh
{
    get
    {
        if (_temperature < _maxTemp)
            return true;
        else
            return false;
    }
}

No problem here but I have a lot of properties in this fashion and I rewrote it into this: 没问题,但是我有很多这种属性,因此我将其重写为:

public double Temperature { get; set; }
public double MaxTemp { get; set; }
public bool IsTempToHigh
{
    get
    {
        if (Temperature < MaxTemp)
            return true;
        else
            return false;
    }
}

Quite a bit cleaner in my opinion and it seems to works just as fine. 我认为还算干净一点,而且效果还不错。 However, I nerver seen or noticed anyone using the property names directly in gettes (or setters), so is it safe to use or might there be any pitfalls. 但是,我不安地看到或注意到有人直接在gettes(或setter)中使用属性名称,因此使用起来安全吗?还是有任何陷阱。

Also why does this compile but gives an StackOverflowException: 也是为什么要编译却给出StackOverflowException:

public double Value
{
    get { return Value; }
    set { Value = value; }
}

If you mean in terms of IsTempTooHigh , that's fine (although the condition is the wrong way round for the name). 如果您用IsTempTooHigh ,那很好(尽管条件是错误的名称名称)。 It's entirely valid to refer to one property within another, although you need to be careful that you don't make it recursive. 在另一个属性中引用一个属性是完全有效的,尽管您需要注意不要使其递归。 Your autoimplemented properties still have backing fields - they've just been generated by the compiler for you rather than being present in your source code. 您自动实现的属性仍然具有后备字段-它们只是由编译器为您生成的,而不是出现在源代码中。

I'd rewrite your computed property without the if , mind you: 我会在没有if情况下重写您的计算属性,请注意:

public bool IsTempTooHigh { get { return Temperature >= MaxTemp; } }

Or in C# 6: 或在C#6中:

public bool IsTempTooHigh => Temperature >= MaxTemp;

As for the stack overflow, it's simplest to imagine they were methods instead: 至于堆栈溢出,最简单的是想象它们是方法:

public double GetValue()
{
    return GetValue();
}

public void SetValue(double value)
{
    SetValue(value);
}

Can you see why calling either of those would cause a stack overflow? 你可以看到为什么叫这类原因会导致堆栈溢出? Well, it's just the same for properties - they're just methods with a bit of metadata linking them, basically. 嗯,属性是一样的-基本上,它们只是带有一些元数据链接它们的方法。

First question: Yes your change makes the code clearer in my opinion. 第一个问题:是的,我认为您的更改使代码更清晰。 A valid case for using backing fields is if you want immutability. 如果需要不变性,则使用备用字段的有效情况是。 The fields are then readonly and you have no setters. 这些字段将变为只读,并且您没有设置器。

Second question: Your setter calls your setter. 第二个问题:你的二传手叫你的二传手。 Which calls your setter. 哪个叫您的二传手。 Which calls your setter. 哪个叫您的二传手。 And so on. 等等。 After a while the stack becomes too large and you get the error. 片刻之后,堆栈变得太大,您将收到错误消息。 :) :)

You can easily use other properties, fields and methods inside your properties. 您可以轻松地在属性内使用其他属性,字段和方法。 No worries at all. 完全不用担心。

Your second code block however, calls the same property over and over again. 但是,您的第二个代码块会反复调用同一属性。 You are trying to mix auto-implemented properties with hand-written properties. 您正在尝试将自动实现的属性与手写的属性混合使用。 That is not possible. 这是不可能的。

Or the compiler generates backing fields for you (when you use auto-implemented properties) or you have to create them yourself (hand-written properties). 或者 ,编译器会为您生成后备字段(当您使用自动实现的属性时), 或者您必须自己创建它们(手写属性)。

So it is either this: 所以要么是这样:

public double Value { get; set; }

Or: 要么:

private double _value;
public double Value
{
    get { return _value; }
    set { _value = value; }
}
  1. It's safe and fine to use property names in private member functions where you currently use the data members. 在当前使用数据成员的私有成员函数中使用属性名称是安全无害的。

  2. That code throws a StackOverFlow exception because by assigning to Value you're actually calling the property. 该代码会引发StackOverFlow异常,因为通过将其赋给Value您实际上是在调用该属性。 Instead, change the name of the underlying data member to be _value : 而是将基础数据成员的名称更改为_value

     public double Value { get { return _value; } set { _value = value; } } 

It is fine to have a property that evaluates 2 other properties. 拥有一个可以评估其他2个属性的属性就可以了。 Of course you easily use a method to do the same job. 当然,您可以轻松地使用一种方法来完成相同的工作。 Eg change 例如变化

public bool IsTempToHigh
{
    get
    {
        if (_temperature < _maxTemp)
            return true;
        else
            return false;
    }
}

to

public bool IsTempToHigh()
{
    return _temperature > _maxTemp;
}

(note: I have changed your < to > assuming this to be correct) (注意:假设正确,我已将您的<更改为>)

You get an exception on your value because you are set the object itself. 因为设置了对象本身,所以您的值会出现异常。 This then changes it's value, so it tries to set itself again.... 然后,这会更改其值,因此会尝试再次进行设置。

so this is wrong... 所以这是错误的...

public double Value
{
    get { return Value; }
    set { Value = value; }
}

but either of the following would be ok 但是以下任何一个都可以

public double Value { get; set;}

or 要么

private double _myVal;

public double MyValue
{
    get{ return _myVal;}
    set{ _myVal = value;}

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM