C# - 每次访问属性时都会重新计算属性吗?

Ale*_*kis 7 c# properties

假设以下简单代码:

private const int A = 2;
private const int B = 3;


public int Result
    {
        get
        {
            return A * B;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我很多次使用Result属性.
每次都会重新计算产品A*B吗?

Not*_*tMe 5

如果您不将值存储在私有字段中,那么它将在每次访问时重新计算.

缓存结果的方法是

private int? _result;
public int Result {
  get {
     if (!_result.HasValue) {
       _result = A*B;
     }
     return _result.Value;
  }
}
Run Code Online (Sandbox Code Playgroud)

这里有几点需要注意.

首先,如果所有操作都是针对常量的,那么编译器会自动为您优化这些操作.这意味着乘法操作实际上不会在运行时执行.这意味着你不应该担心它.

其次,如果操作仅限于对两个现有变量执行简单的算术运算,那么每次计算它将比上面的"if"测试更快.此外,在这种情况下,带有私有字段的本地存储会增加内存占用,这是没有用的原因.

第三,如果底层变量在对属性getter的调用之间发生了变化(即A或B有一个新值),那么这将不会重新计算这些新值.

这使得我们实际使用上述代码的几个原因之一:操作需要很长时间,并且它操作的数据在对属性的调用之间没有变化.我现在想到的另一个原因就是如果属性是一个必须在调用之前被实例化的对象.


Mar*_*man 3

在反射器中打开程序集,编译器将优化乘法,因为它们是const int

public class FooContainer
{
    private const int A = 2;
    private const int B = 3;


    public int Result
    {
        get
        {
            return A * B;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

会变成:

public class FooContainer
{
    // Fields
    private const int A = 2;
    private const int B = 3;

    // Properties
    public int Result
    {
        get
        {
            return 6;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您将变量更改为简单int且不存储计算,则每次都会进行评估。

例子:

public class FooContainer
{
    private int A = 2;
    private const int B = 3;


    public int Result
    {
        get
        {
            return A * B;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

变成:

public class FooContainer
{
    // Fields
    private int A = 2;
    private const int B = 3;

    // Properties
    public int Result
    {
        get
        {
            return (this.A * 3);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)