Dic*_*ges 26 c# c#-6.0 null-conditional-operator
提前道歉:这个问题来自一个试图学习高级C#的硬核,未经过改造的C++开发人员.考虑以下:
if (myUserDefinedObject != null)
{
myUserDefinedObject.ToString();
}
Run Code Online (Sandbox Code Playgroud)
这显然不是线程安全的.另一方面,我看过两个教程说?(例如,Null条件运算符或'Elvis运算符')
myUserDefinedObject?.ToString();
Run Code Online (Sandbox Code Playgroud)
IS线程安全.除非编译器将[mutex?]锁定在它下面(颤抖),否则我不明白这是怎么回事.如果这个成语是线程安全的,有人可以指点我如何完成它的技术描述?如果它不是线程安全的,那么有没有人有一个实际上说它不是的参考?
Eri*_*ert 33
我想澄清BJ迈尔斯的(正确的)答案.
在C#中,事件可以被认为是委托类型的字段 - 正如属性可以被认为是属性类型的字段 - 并且该"字段"的值可以为空.如果你在一个线程上修改事件处理程序而另一个线程试图调用它的情况很糟糕,你可以进入以下情况:
if (this.SomeEvent != null)
this.SomeEvent( ... );
Run Code Online (Sandbox Code Playgroud)
不是线程安全的.该值可以被突变,以便在检查之前为非null,在检查之后为null,并且程序崩溃.
使这个"线程安全"的常用方法,我使用的术语是将值复制到本地,然后测试本地为null.这样做的好处是不会因空取消引用而崩溃.然而,聪明的开发人员会注意到还有一场比赛!顺序可以是
所以从这个意义上讲,这种模式不是"线程安全的".如果您处于这种不幸的位置,您有责任确保实施适当的线程逻辑,以便不会发生这种情况.你可以随心所欲地做到这一点.如果你想要在一个线程上调用一个事件处理程序同时在另一个线程上改变事件的(可疑的)好处,那么你必须付钱以使其安全,或者处理竞争条件错误.
我个人会像瘟疫一样避免这种情况,但我不够聪明,无法编写正确的多线程代码.
现在,至于实际问题:
some_expression ?. ToString();
Run Code Online (Sandbox Code Playgroud)
是相同的
temp = some_expression
temp == null ? null : temp.ToString()
Run Code Online (Sandbox Code Playgroud)
你认为后一个代码是"线程安全的"吗?
BJ *_*ers 27
来自MSDN(强调我的):
null条件成员访问的另一个用途是以线程安全的方式使用更少的代码调用委托.旧方法需要如下代码:
Run Code Online (Sandbox Code Playgroud)var handler = this.PropertyChanged; if (handler != null) handler(…)新方法更简单:
Run Code Online (Sandbox Code Playgroud)PropertyChanged?.Invoke(e)新方法是线程安全的,因为编译器只生成一次评估PropertyChanged的代码,将结果保存在临时变量中.
因此,这里不涉及锁定 - 通过创建本地临时变量来强制执行线程安全性,这可以防止不同的线程在null检查和其他操作之间修改该变量.
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |