对象/方法链接方法调用中的C#竞争条件和Null条件运算符

对象/方法链接方法调用中的C#竞争条件和Null条件运算符,c#,race-condition,method-chaining,null-conditional-operator,C#,Race Condition,Method Chaining,Null Conditional Operator,我知道在各种情况下都会问这个问题,但如果我不够谨慎的话,我没有找到确切的问题或满意的答案 症状: 当有嵌套对象时,例如Class A引用Class B引用Class C具有类似MyCall()的函数,并且我必须调用此函数,但我不能确定是否有任何类被释放或为null,我通常使用作为简化调用: myClassC?.myClassB?.myClassC?.MyCall(); 这通常工作正常,但在极少数情况下,运行带有NullReferenceException的stops 例如,当在代码中的某个位置

我知道在各种情况下都会问这个问题,但如果我不够谨慎的话,我没有找到确切的问题或满意的答案

症状:

当有嵌套对象时,例如
Class A
引用
Class B
引用
Class C
具有类似
MyCall()
的函数,并且我必须调用此函数,但我不能确定是否有任何类被释放或为null,我通常使用作为简化调用:

myClassC?.myClassB?.myClassC?.MyCall();
这通常工作正常,但在极少数情况下,运行带有
NullReferenceException
的stops

例如,当在代码中的某个位置调用
ClientSession?.WebsocketConnection?.SocketConnection?.Disconnect()
以断开客户端套接字时,会发生这种情况,但当此调用异步运行时,客户端会远程断开连接,例如
SocketConnection
类会被释放

因此,竞争条件会导致这样一种情况,即null检查实际上可以在最后到达函数调用,但当执行发生时,链中的任何对象都会变为null,因此无法执行该方法,从而导致
NullReferenceException

问题:

避免这种情况的正确方法是什么?不使用
try/catch
,因为这是一个性能敏感的应用程序,而且关于我的基准测试,捕获这样的错误有点昂贵

如果任何对象为空,是否有适当的方法取消执行


谢谢您的帮助。

myClassC?.MyCall()
编译成类似于
var tmp=myClassC;如果(tmp!=null)tmp.MyCall()
;属性访问也是如此。如果您得到一个NRE,它可能会从其中一个属性访问/方法调用中抛出:null条件运算符本身不会抛出一个。NRE的确切堆栈跟踪是什么?可能是
ClientSession?.WebsocketConnection?.SocketConnection?.Disconnect()??AnyThing()
@canton7-我知道它是(if!=null)的简写,我只是希望它能更智能地检查。我现在不能显示堆栈跟踪,因为这是一个竞争条件问题,它很少发生,所以我手头没有它,但当代码停止运行时,通常第一个对象为null,而不是最后一个。当中间的一个为null时也会发生同样的情况。我尝试复制它,但不能保证,所以不要等待。@SalahAkbari-这可能只在(我猜)最后的方法返回null时有用,而不是在调用该方法时任何其他对象都返回null时有用。这是一个竞争条件问题,而不是空对象问题。该方法不需要返回任何值,它必须执行代码,它可能只是一个空函数。@beatcoder我的观点是它为空检查副本(我称之为
tmp
)。在检查null和访问名为/property的方法(有趣的是,除非您处理的是作为字段的可空值类型)之间,某个对象不可能变为null。