为什么 readonly 和 volatile 修饰符是互斥的?

发布于 2024-07-10 03:10:33 字数 413 浏览 6 评论 0原文

我有一个只读的引用类型变量,因为引用永远不会改变,只会改变它的属性。 当我尝试向其添加 volatile 修饰符时,编译警告我它不会让两个修饰符应用于同一个变量。 但我认为我需要它是易失性的,因为我不想在读取其属性时出现缓存问题。 我错过了什么吗? 还是编译器错误?

更新 正如 Martin 在下面的评论之一中所述:对于引用类型对象,readonly 和 volatile 修饰符仅适用于引用,而不适用于对象的属性。 这就是我所缺少的,所以编译器是正确的。

class C
{
    readonly volatile string s;  // error CS0678: 'C.s': a field cannot be both volatile and readonly
}

I have a reference-type variable that is readonly, because the reference never change, only its properties. When I tried to add the volatile modifier to it the compiled warned me that it wouldn't let both modifiers apply to the same variable. But I think I need it to be volatile because I don't want to have caching problems when reading its properties. Am I missing anything? Or is the compiler wrong?

Update As Martin stated in one of the comments below: Both readonly and volatile modifiers apply only to the reference, and not to the object's properties, in the case of reference-type objects. That is what I was missing, so the compiler is right.

class C
{
    readonly volatile string s;  // error CS0678: 'C.s': a field cannot be both volatile and readonly
}

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

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

发布评论

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

评论(3

清欢 2024-07-17 03:10:33

readonlyvolatile 修饰符都不是穿透性的。 它们适用于引用本身,而不是对象的属性。

readonly 关键字断言并强制变量在初始化后不能更改。 变量是存储引用的一小块内存。

volatile 关键字告诉编译器变量的内容可能会被多个线程更改。 这可以防止编译器使用可能导致并发访问问题的优化(例如将变量的值读入寄存器并在多个指令上使用该值)。 同样,这只会影响存储引用的一小块内存。

这样应用,你就会发现它们确实是互斥的。 如果某些内容是只读的(只能在初始化或构造时写入一次),那么它也不能是易失性的(可以由多个线程随时写入)。


至于您对缓存问题的担忧,IIRC,关于编译器何时可以缓存属性调用的结果有相当严格的规则。 请记住,它方法调用,并且(从编译器的角度来看)缓存其值并跳过再次调用它是一项相当繁重的优化。 我不认为这是你需要过度担心的事情。

Neither the readonly nor volatile modifiers are penetrative. They apply to the reference itself, not the object's properties.

The readonly keyword asserts—and enforces—that a variable cannot change after initialization. The variable is the small chunk of memory where the reference is stored.

The volatile keyword tells the compiler that the contents of a variable might be changed by multiple threads. This prevents the compiler from using optimizations (such as reading the variable's value into a register and using that value over several instructions) that might cause problems with concurrent access. Again, this only affects the small chunk of memory where the reference is stored.

Applied this way, you can see that they are indeed mutually exclusive. If something is readonly (can only be written to once, at initialization or construction), then it can't also be volatile (can be written to at any time by multiple threads).


As for your concern about caching issues, IIRC, there are pretty strict rules about when the compiler can cache the result of a property call. Keep in mind that it is a method call, and it's a pretty heavy optimization (from the compiler's stand-point) to cache its value and skip calling it again. I don't think it's something you need to concern yourself with overly much.

此生挚爱伱 2024-07-17 03:10:33

只读字段只能在首次构造对象时写入。 因此,CPU 上不会出现任何缓存问题,因为该字段是不可变的并且不可能更改。

A readonly field can only be written when the object is first constructed. Therefore there won't be any caching issue on the CPU because the field is immutable and can't possibly change.

岛徒 2024-07-17 03:10:33

虽然引用本身可能是线程安全的,但其属性可能不是。 考虑一下如果两个线程尝试同时迭代引用对象中包含的 List,会发生什么情况。

While the reference itself might be thread-safe, its properties might not. Think about what would happen if two threads tried to simultaneously iterate through a List contained within your reference object.

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