财产决定论

发布于 2024-09-19 08:04:01 字数 180 浏览 8 评论 0原文

C# 中有没有办法将属性标记为确定性?

我问的原因是我经常发现自己声明一个局部变量并将属性读入其中,而不是多次访问该属性。

有什么方法可以将属性装饰为确定性的,以便编译器可以优化对该属性的多次访问?我猜测在这种情况下,该类需要是不可变的,并进行这样的装饰。

这是真的存在的东西还是我抓住了救命稻草?

Is there any way in C# to mark a property as deterministic?

The reason I ask is that I often find myself declaring a local variable and reading a property into it, instead of accessing the property multiple times.

Is there any way that I can decorate the property as deterministic, such that the compiler could then optimize multiple accesses to that property? I am guessing in such a scenario that the class would need to be immutable, and decorated as such.

Is this something that even exists or am I clutching at straws?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倾其所爱 2024-09-26 08:04:01

如果属性很简单,例如隐式属性:

public int X { get; set; }

或从局部变量读取:

public int X { get { return _x; } }

那么编译器将优化代码,以便多次访问该属性与将属性放入变量并访问该属性之间没有区别。

我通过比较访问属性十次的 1 亿次迭代和将属性复制到变量并访问该十次来验证这一点,并且根本没有可测量的差异。

一般来说,属性应该是轻量级的,这样您就不必在每次访问它时都进行繁重的处理。如果属性值的获取成本很高,则类应该在内部缓存该值,以便读取属性只会在第一次执行成本高昂的操作(延迟加载模式)。

如果每次获取一个属性的成本都很高,那么它根本不应该是一个属性,而应该是一个 getter 方法。

If the property is simple, like an implicit property:

public int X { get; set; }

or reading from a local variable:

public int X { get { return _x; } }

then the compiler will optimise the code so that there is no difference between accessing the property multiple times and putting the property in a variable and access that.

I verified this by comparing 100 million iterations of accessing a property ten times and copying the property to a variable and access that ten times, and there is no measuarable difference at all.

Generally properties should be leight-weight, so that you don't have to expect any heavy processing each time you access it. If the value for the property is costly to get, the class should cache the value internally so that reading the property only makes the costly operation the first time (lazy loading pattern).

If a property is costly to get each time, it shouldn't be a property at all, but a getter method.

盗梦空间 2024-09-26 08:04:01

C# 中没有任何机制允许您引入 const 属性 getter,即不更改对象状态的 getter。

Microsoft 文档只是建议不要在您的应用程序中引入任何副作用吸气剂:

使用 get 访问器更改对象的状态是一种不好的编程风格。例如,以下访问器会产生副作用:每次访问数字字段时都会更改对象的状态。

私有整数;
公共整数号
{
    得到
    {
        返回数字++; // 不要这样做
    }
}

正如 Daren 所提到的,要考虑的另一个方面是多线程(除非您的对象确实是不可变的)。如果另一个线程更改了对象状态,以便 getter 在第二次调用时返回不同的值,该怎么办?编译器没有简单的方法可以做出任何保证,例如在下面的场景中:

class List
{
    IList data;

    // called several times on thread A
    // property has no side-effects
    public int Count { get data.Length; }

    // called several times on thread B
    public void Add(object o)
    {
        data.Add(o);
    }
}

There is no mechanism in C# that allows you to introduce const property getters, i.e. getters that do not change the state of the object.

The Microsoft documentation simply recommends not to introduce any side-effects in your getters:

It is a bad programming style to change the state of the object by using the get accessor. For example, the following accessor produces the side effect of changing the state of the object every time that the number field is accessed.

private int number;
public int Number
{
    get
    {
        return number++;   // Don't do this
    }
}

As mentioned by Daren, another aspect to consider is multi-threading (unless your object is truly immutable). What if another thread changed the object state so that the getter should return a different value on the second call? There is no easy way for the compiler to make any guarantees, e.g. in the scenario below:

class List
{
    IList data;

    // called several times on thread A
    // property has no side-effects
    public int Count { get data.Length; }

    // called several times on thread B
    public void Add(object o)
    {
        data.Add(o);
    }
}
清旖 2024-09-26 08:04:01

我猜您正在寻找只读,但是我不确定性能与局部变量相比如何。而且它只适用于字段,不适用于属性。

此外,只读并不意味着确定性。

private readonly List<string> fixedList = new List<string>();

仅仅意味着fixedList对象不能被替换,但是内容仍然可以改变。

I guess you're looking for readonly, however I'm not sure about how the performance is compared to a local variable. And it is only applicable to fields, not properties.

Besides readonly does not imply determinism.

private readonly List<string> fixedList = new List<string>();

just means that the fixedList object can not be replaced, but the content can still be changed.

情深已缘浅 2024-09-26 08:04:01

除非您的属性的支持字段是只读的,否则您将如何解决线程问题?

Unless the backing field of your property is readonly, how are you going to account for threading issues?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文